mangrove 0.34.0 → 0.35.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1dfe08aeea0151d419caef995589fe18b98674aeb78817f651d58eef0b45e552
4
- data.tar.gz: 070b2971e1f62072b6e26289fe7e04f0f5527c414db63664cb76ef82c19b9ffd
3
+ metadata.gz: b672fc8a3a469a1d00a066bbc9781acbfd0229e5acf40f4d05452a3db9bd6ff2
4
+ data.tar.gz: 1fd9cdd284c43bbceb6b0bc44d21f358cc85d9fef1a5a3d6e9244529aa072279
5
5
  SHA512:
6
- metadata.gz: 75bc64b315237e3e0c44ce8245a13e4562daf2ac2444cd3aff98151869f3c3f796259b9f62ab3d3b5fc2a58749033e3839e44d86785c20f0ec1a6b3a51e23474
7
- data.tar.gz: 60204fffda1d393f5d1b6b0c893c29757d66c14c149685b0e138d2b1e86926da61784315f789c45dcec549dd564cc87f0c7166f9c5f259ce9de05081d41ddac2
6
+ metadata.gz: c85f28b501f523e3d541a19a64cc560f252ce72479e1df036b75c09dfec4d43843169a614922ce1aece40867434cd5b471aaa2e4eb37337f8694f38971dc491f
7
+ data.tar.gz: a806cd4beb648c60e7e5ceed320ca63d0e9033b7d940fc14fbd0a3254b44b2a657704cf5ee82097aad991b11d7bf0285f99fa0bbe1946ecb5492e6f49f76fe1b
data/.rubocop.yml CHANGED
@@ -35,6 +35,7 @@ Naming/VariableNumber:
35
35
  EnforcedStyle: snake_case
36
36
 
37
37
  Style/BlockDelimiters:
38
+ Enabled: false
38
39
  EnforcedStyle: always_braces
39
40
  AllowedMethods:
40
41
  - describe
data/README.md CHANGED
@@ -2,18 +2,18 @@
2
2
 
3
3
  Mangrove is a Ruby toolkit that brings a functional, statically-typed flavor to your Sorbet-enabled projects. Inspired by concepts from languages like Rust and Haskell, Mangrove provides a robust set of tools—primarily `Result` and ADT-like Enums—to help you write safer, more expressive Ruby code.
4
4
 
5
- - **[Documentation](https://kazzix14.github.io/mangrove/docs/)**
6
- - **[Coverage](https://kazzix14.github.io/mangrove/coverage/index.html#_AllFiles)**
5
+ - [Documentation](https://kazzix14.github.io/mangrove/docs/)
6
+ - [Coverage](https://kazzix14.github.io/mangrove/coverage/index.html#_AllFiles)
7
7
 
8
8
  ---
9
9
 
10
10
  ## Highlights
11
11
 
12
12
  - **Sorbet Integration**
13
- Built from the ground up to work smoothly with Sorbets type system.
13
+ Built from the ground up to work smoothly with Sorbet's type system.
14
14
 
15
15
  - **Result Type**
16
- Model success/failure outcomes with explicit types—no more return false or nil for errors!
16
+ Model success/failure outcomes with explicit types—no more "return false or nil" for errors!
17
17
 
18
18
  - **Enums (ADTs)**
19
19
  Define your own sealed enums with typed variants. Each variant can hold distinct inner data.
@@ -33,17 +33,17 @@ bundle add mangrove
33
33
 
34
34
  ## Usage Overview
35
35
 
36
- Mangrove revolves around **`Result`** and a sealed Enum mechanism for ADTs.
36
+ Mangrove revolves around **`Result`** and a sealed "Enum" mechanism for ADTs.
37
37
 
38
38
  ### Result
39
39
 
40
40
  A `Result` is either `Ok(T)` or `Err(E)`. You can compose them with monadic methods like `and_then` and `or_else`.
41
- For early returns in a functional style, you have two main approaches:
41
+ For "early returns" in a functional style, you have two main approaches:
42
42
 
43
43
  1. **A context-based DSL (e.g., `ctx.try!`)**
44
44
  2. **An instance method on `Result` itself, `unwrap_in(ctx)`**, which behaves similarly.
45
45
 
46
- Heres an example of chaining requests and short-circuiting on error:
46
+ Here's an example of chaining requests and short-circuiting on error:
47
47
 
48
48
  ```ruby
49
49
  class MyClient
@@ -87,6 +87,32 @@ end
87
87
  # More chaining, etc...
88
88
  ```
89
89
 
90
+ ### Extension Methods
91
+
92
+ Mangrove provides convenient extension methods through `Mangrove::Result::Ext`. These methods allow you to easily wrap any value in a `Result`:
93
+
94
+ ```ruby
95
+ # Include the extension in your classes
96
+ class Object
97
+ include Mangrove::Result::Ext
98
+ end
99
+
100
+ # Now you can use in_ok and in_err on any object
101
+ "success".in_ok # => Result::Ok("success")
102
+ "error".in_err # => Result::Err("error")
103
+
104
+ # Useful in method chains
105
+ "hello"
106
+ .upcase
107
+ .in_ok
108
+ .map_ok { |s| "#{s}!" } # => Result::Ok("HELLO!")
109
+
110
+ # Error case
111
+ "error message"
112
+ .in_err
113
+ .map_err { |e| "#{e}!" } # => Result::Err("error message!")
114
+ ```
115
+
90
116
  ### Enums (ADTs)
91
117
 
92
118
  Define an enum with typed variants:
@@ -0,0 +1,18 @@
1
+ # typed: true
2
+ # frozen_string_literal: true
3
+
4
+ module Mangrove
5
+ module Result
6
+ module Ext
7
+ extend T::Sig
8
+
9
+ def in_ok
10
+ Mangrove::Result::Ok.new(self)
11
+ end
12
+
13
+ def in_err
14
+ Mangrove::Result::Err.new(self)
15
+ end
16
+ end
17
+ end
18
+ end
@@ -2,6 +2,7 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require_relative "result/control_signal"
5
+ require_relative "result/ext"
5
6
 
6
7
  module Mangrove
7
8
  # Result is a type that represents either success (`Ok`) or failure (`Err`).
@@ -2,5 +2,5 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  module Mangrove
5
- VERSION = "0.34.0"
5
+ VERSION = "0.35.0"
6
6
  end
@@ -0,0 +1,40 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ require "mangrove/result/ext"
5
+ require "tapioca/dsl"
6
+ require "sorbet-runtime"
7
+
8
+ module Tapioca
9
+ module Compilers
10
+ class MangroveResultExt < Tapioca::Dsl::Compiler
11
+ extend T::Sig
12
+
13
+ ConstantType = type_member { { fixed: T.class_of(Mangrove::Result::Ext) } }
14
+
15
+ sig { override.returns(T::Enumerable[Module]) }
16
+ def self.gather_constants
17
+ all_classes.select { |c| c < ::Mangrove::Result::Ext }
18
+ end
19
+
20
+ sig { override.void }
21
+ def decorate
22
+ return unless valid_constant_name?(constant.to_s)
23
+
24
+ root.create_path(constant) do |klass|
25
+ klass.create_method("in_ok", return_type: "Mangrove::Result::Ok[#{constant}]")
26
+ klass.create_method("in_err", return_type: "Mangrove::Result::Err[#{constant}]")
27
+ end
28
+ rescue NameError
29
+ # 握りつぶす
30
+ end
31
+
32
+ private
33
+
34
+ sig { params(string: String).returns(T::Boolean) }
35
+ def valid_constant_name?(string)
36
+ Object.const_defined?(string) && !!(string =~ /\A[A-Z][a-zA-Z0-9_]*\z/)
37
+ end
38
+ end
39
+ end
40
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mangrove
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.34.0
4
+ version: 0.35.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kazuma Murata
@@ -46,8 +46,10 @@ files:
46
46
  - lib/mangrove/option/control_signal.rb
47
47
  - lib/mangrove/result.rb
48
48
  - lib/mangrove/result/control_signal.rb
49
+ - lib/mangrove/result/ext.rb
49
50
  - lib/mangrove/version.rb
50
51
  - lib/tapioca/dsl/compilers/mangrove_enum.rb
52
+ - lib/tapioca/dsl/compilers/mangrove_result_ext.rb
51
53
  - rbi/mangrove.rbi
52
54
  - sig/mangrove.rbs
53
55
  - sorbet/config