bcdd-result 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8a41105b84f902004736a171bd42c943923ee188d14fe6630bf379fb3e3ef158
4
- data.tar.gz: 7b879ee4c04c2b60e95d1c2af18e28c8e7f1edb475c0cdb8274c56f6a577198a
3
+ metadata.gz: 96c58d6a9132fbf42fc8f3c1d9ba683f0b6297e23b1f0536fc4bcb7efb5084df
4
+ data.tar.gz: fcef45f3c5ddacc20ff5e9533012c7fbe5817878cef1ff528dabd8920e1cbccd
5
5
  SHA512:
6
- metadata.gz: 48e9dd67d1f69a4b9aae0bbf1166aab532ca2f8cdc8883bf303b5a41f702a77c8531c4ae2baa96bf256a828e9db0624d631c1259e0870c9ee22ecd65b4ed2ce9
7
- data.tar.gz: cb2a0e618b21a4bf98c61b0a4dabfac322efe4293eab18c84cf729df920c49bf47557dcf20ceb01c42ac7c4673fa6fb55c235a2e93f2555a2021cbbfb3f37b36
6
+ metadata.gz: d4cf048907571205c6cd0b90ca4b95c2480c34de79d082132e4f1cab1e809f4c6eec538d9d38b036ad313d9653420625b68a502272e73371b99b157f43315123
7
+ data.tar.gz: 4662aaeb33a7eb770ab51529cc1f2c4e9d86844dec70dfcdc4f37674aab33d010d6cbe7932fc635f09979d47b4b631748a3d4791021e99108a011a93469a2d73
data/.rubocop_todo.yml CHANGED
@@ -1,12 +1,12 @@
1
1
  # This configuration was generated by
2
2
  # `rubocop --auto-gen-config`
3
- # on 2023-09-25 17:14:03 UTC using RuboCop version 1.56.3.
3
+ # on 2023-09-27 00:47:03 UTC using RuboCop version 1.56.3.
4
4
  # The point is for the user to remove these configuration records
5
5
  # one by one as the offenses are removed from the code base.
6
6
  # Note that changes in the inspected code, or installation of new
7
7
  # versions of RuboCop, may require this file to be generated again.
8
8
 
9
- # Offense count: 9
9
+ # Offense count: 13
10
10
  # Configuration parameters: AllowedConstants.
11
11
  Style/Documentation:
12
12
  Exclude:
@@ -15,5 +15,7 @@ Style/Documentation:
15
15
  - 'lib/bcdd/result.rb'
16
16
  - 'lib/bcdd/result/error.rb'
17
17
  - 'lib/bcdd/result/failure.rb'
18
+ - 'lib/bcdd/result/handler.rb'
18
19
  - 'lib/bcdd/result/success.rb'
20
+ - 'lib/bcdd/result/type.rb'
19
21
  - 'lib/bcdd/resultable.rb'
data/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.3.0] - 2023-09-26
4
+
5
+ ### Added
6
+
7
+ - Add `BCDD::Result#handle`. This method allows defining blocks for each hook (type, failure, success), but instead of returning the result itself, it will return the output of the first match/block execution.
8
+
3
9
  ## [0.2.0] - 2023-09-26
4
10
 
5
11
  ### Added
data/README.md CHANGED
@@ -14,6 +14,7 @@ Furthermore, this abstraction exposes several features that will be useful to ma
14
14
 
15
15
  Use it to enable the [Railway Oriented Programming](https://fsharpforfunandprofit.com/rop/) pattern (superpower) in your code.
16
16
 
17
+ - [Ruby Version](#ruby-version)
17
18
  - [Installation](#installation)
18
19
  - [Usage](#usage)
19
20
  - [Reference](#reference)
@@ -24,6 +25,7 @@ Use it to enable the [Railway Oriented Programming](https://fsharpforfunandprofi
24
25
  - [`result.on_type`](#resulton_type)
25
26
  - [`result.on_success`](#resulton_success)
26
27
  - [`result.on_failure`](#resulton_failure)
28
+ - [`result.handle`](#resulthandle)
27
29
  - [Result Value](#result-value)
28
30
  - [`result.value_or`](#resultvalue_or)
29
31
  - [`result.data_or`](#resultdata_or)
@@ -39,18 +41,26 @@ Use it to enable the [Railway Oriented Programming](https://fsharpforfunandprofi
39
41
  - [License](#license)
40
42
  - [Code of Conduct](#code-of-conduct)
41
43
 
44
+ ## Ruby Version
45
+
46
+ `>= 2.7.0`
47
+
42
48
  ## Installation
43
49
 
44
- Install the gem and add to the application's Gemfile by executing:
50
+ Add this line to your application's Gemfile:
45
51
 
46
- $ bundle add bcdd-result
52
+ ```ruby
53
+ gem 'bcdd-result', require: 'bcdd/result'
54
+ ```
55
+
56
+ And then execute:
57
+
58
+ $ bundle install
47
59
 
48
60
  If bundler is not being used to manage dependencies, install the gem by executing:
49
61
 
50
62
  $ gem install bcdd-result
51
63
 
52
- > **NOTE:** This gem is compatible with Ruby >= 2.7.0
53
-
54
64
  <p align="right">(<a href="#-bcddresult">⬆️ &nbsp;back to top</a>)</p>
55
65
 
56
66
  ## Usage
@@ -263,6 +273,52 @@ divide(4, 0).on_failure(:invalid_arg) { |error| puts error }
263
273
 
264
274
  <p align="right">(<a href="#-bcddresult">⬆️ &nbsp;back to top</a>)</p>
265
275
 
276
+ #### `result.handle`
277
+
278
+ This method will allow you to define blocks for each hook (type, failure, success), but instead of returning itself, it will return the output of the first match/block execution.
279
+
280
+ ```ruby
281
+ divide(4, 2).handle do |result|
282
+ result.success { |number| number }
283
+ result.failure(:invalid_arg) { |err| puts err }
284
+ result.type(:division_by_zero) { raise ZeroDivisionError }
285
+ end
286
+
287
+ #or
288
+
289
+ divide(4, 2).handle do |on|
290
+ on.success { |number| number }
291
+ on.failure { |err| puts err }
292
+ end
293
+
294
+ #or
295
+
296
+ divide(4, 2).handle do |on|
297
+ on.type(:invalid_arg) { |err| puts err }
298
+ on.type(:division_by_zero) { raise ZeroDivisionError }
299
+ on.type(:division_completed) { |number| number }
300
+ end
301
+
302
+ # or
303
+
304
+ divide(4, 2).handle do |on|
305
+ on[:invalid_arg] { |err| puts err }
306
+ on[:division_by_zero] { raise ZeroDivisionError }
307
+ on[:division_completed] { |number| number }
308
+ end
309
+
310
+ # The [] syntax 👆 is an alias of #type.
311
+ ```
312
+
313
+ **Notes:**
314
+ * You can define multiple types to be handled by the same hook/block
315
+ * If the type is missing, it will perform the block for any success or failure handler.
316
+ * The `#type` and `#[]` handlers will require at least one type/argument.
317
+
318
+ *PS: The `divide()` implementation is [here](#result-hooks).*
319
+
320
+ <p align="right">(<a href="#-bcddresult">⬆️ &nbsp;back to top</a>)</p>
321
+
266
322
  ### Result Value
267
323
 
268
324
  The most simple way to get the result value is by calling `BCDD::Result#value` or `BCDD::Result#data`.
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ class BCDD::Result
4
+ class Handler
5
+ UNDEFINED = ::Object.new
6
+
7
+ def initialize(result)
8
+ @outcome = UNDEFINED
9
+
10
+ @_type = result._type
11
+ @result = result
12
+ end
13
+
14
+ def [](*types, &block)
15
+ raise Error::MissingTypeArgument if types.empty?
16
+
17
+ self.outcome = block if _type.in?(types, allow_empty: false)
18
+ end
19
+
20
+ def failure(*types, &block)
21
+ self.outcome = block if result.failure? && _type.in?(types, allow_empty: true)
22
+ end
23
+
24
+ def success(*types, &block)
25
+ self.outcome = block if result.success? && _type.in?(types, allow_empty: true)
26
+ end
27
+
28
+ alias type []
29
+
30
+ private
31
+
32
+ attr_reader :_type, :result
33
+
34
+ def outcome?
35
+ @outcome != UNDEFINED
36
+ end
37
+
38
+ def outcome
39
+ @outcome if outcome?
40
+ end
41
+
42
+ def outcome=(block)
43
+ @outcome = block.call(result.value, result.type) unless outcome?
44
+ end
45
+ end
46
+
47
+ private_constant :Handler
48
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ class BCDD::Result
4
+ class Type
5
+ attr_reader :to_sym
6
+
7
+ def initialize(type)
8
+ @to_sym = type.to_sym
9
+ end
10
+
11
+ def in?(types, allow_empty: false)
12
+ (allow_empty && types.empty?) || types.any?(to_sym)
13
+ end
14
+ end
15
+
16
+ private_constant :Type
17
+ end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module BCDD
4
4
  class Result
5
- VERSION = '0.2.0'
5
+ VERSION = '0.3.0'
6
6
  end
7
7
  end
data/lib/bcdd/result.rb CHANGED
@@ -2,22 +2,28 @@
2
2
 
3
3
  require_relative 'result/version'
4
4
  require_relative 'result/error'
5
+ require_relative 'result/type'
6
+ require_relative 'result/handler'
5
7
  require_relative 'result/failure'
6
8
  require_relative 'result/success'
7
9
 
8
10
  require_relative 'resultable'
9
11
 
10
12
  class BCDD::Result
11
- attr_reader :type, :value, :subject
13
+ attr_reader :_type, :value, :subject
12
14
 
13
15
  protected :subject
14
16
 
15
17
  def initialize(type:, value:, subject: nil)
16
- @type = type.to_sym
18
+ @_type = Type.new(type)
17
19
  @value = value
18
20
  @subject = subject
19
21
  end
20
22
 
23
+ def type
24
+ _type.to_sym
25
+ end
26
+
21
27
  def success?(_type = nil)
22
28
  raise Error::NotImplemented
23
29
  end
@@ -46,15 +52,15 @@ class BCDD::Result
46
52
  def on(*types)
47
53
  raise Error::MissingTypeArgument if types.empty?
48
54
 
49
- tap { yield(value, type) if expected_type?(types) }
55
+ tap { yield(value, type) if _type.in?(types, allow_empty: false) }
50
56
  end
51
57
 
52
58
  def on_success(*types)
53
- tap { yield(value, type) if success? && allowed_to_handle?(types) }
59
+ tap { yield(value, type) if success? && _type.in?(types, allow_empty: true) }
54
60
  end
55
61
 
56
62
  def on_failure(*types)
57
- tap { yield(value, type) if failure? && allowed_to_handle?(types) }
63
+ tap { yield(value, type) if failure? && _type.in?(types, allow_empty: true) }
58
64
  end
59
65
 
60
66
  def and_then(method_name = nil)
@@ -67,20 +73,20 @@ class BCDD::Result
67
73
  ensure_result_object(result, origin: :block)
68
74
  end
69
75
 
76
+ def handle
77
+ handler = Handler.new(self)
78
+
79
+ yield handler
80
+
81
+ handler.send(:outcome)
82
+ end
83
+
70
84
  alias data value
71
85
  alias data_or value_or
72
86
  alias on_type on
73
87
 
74
88
  private
75
89
 
76
- def expected_type?(types)
77
- types.any?(type)
78
- end
79
-
80
- def allowed_to_handle?(types)
81
- types.empty? || expected_type?(types)
82
- end
83
-
84
90
  def call_subject_method(method_name)
85
91
  method = subject.method(method_name)
86
92
 
data/sig/bcdd/result.rbs CHANGED
@@ -5,12 +5,14 @@ module BCDD
5
5
  end
6
6
 
7
7
  class BCDD::Result
8
- attr_reader type: Symbol
8
+ attr_reader _type: BCDD::Result::Type
9
9
  attr_reader value: untyped
10
10
  attr_reader subject: untyped
11
11
 
12
12
  def initialize: (type: Symbol, value: untyped, ?subject: untyped) -> void
13
13
 
14
+ def type: -> Symbol
15
+
14
16
  def success?: (?Symbol type) -> bool
15
17
  def failure?: (?Symbol type) -> bool
16
18
 
@@ -29,14 +31,14 @@ class BCDD::Result
29
31
 
30
32
  def and_then: (?Symbol method_name) { (untyped) -> untyped } -> BCDD::Result
31
33
 
34
+ def handle: { (BCDD::Result::Handler) -> void } -> untyped
35
+
32
36
  alias data value
33
37
  alias data_or value_or
34
38
  alias on_type on
35
39
 
36
40
  private
37
41
 
38
- def expected_type?: (Array[Symbol]) -> bool
39
- def allowed_to_handle?: (Array[Symbol]) -> bool
40
42
  def call_subject_method: (Symbol) -> BCDD::Result
41
43
  def ensure_result_object: (untyped, origin: Symbol) -> BCDD::Result
42
44
  end
@@ -55,6 +57,31 @@ class BCDD::Result
55
57
  def self.Failure: (Symbol type, ?untyped value) -> BCDD::Result::Failure
56
58
  end
57
59
 
60
+ class BCDD::Result
61
+ class Handler
62
+ UNDEFINED: Object
63
+
64
+ def initialize: (BCDD::Result) -> void
65
+
66
+ def []: (*Symbol) { (untyped, Symbol) -> void } -> untyped
67
+ def failure: (*Symbol) { (untyped, Symbol) -> void } -> untyped
68
+ def success: (*Symbol) { (untyped, Symbol) -> void } -> untyped
69
+
70
+ alias type []
71
+
72
+ private
73
+
74
+ attr_reader _type: BCDD::Result::Type
75
+ attr_reader result: BCDD::Result
76
+
77
+ def outcome?: -> bool
78
+
79
+ def outcome: -> untyped
80
+
81
+ def outcome=: (Proc) -> void
82
+ end
83
+ end
84
+
58
85
  module BCDD
59
86
  module Resultable
60
87
  def Success: (Symbol type, ?untyped value) -> BCDD::Result::Success
@@ -63,6 +90,16 @@ module BCDD
63
90
  end
64
91
  end
65
92
 
93
+ class BCDD::Result
94
+ class Type
95
+ attr_reader to_sym: Symbol
96
+
97
+ def initialize: (Symbol) -> void
98
+
99
+ def in?: (Array[Symbol], allow_empty: bool) -> bool
100
+ end
101
+ end
102
+
66
103
  class BCDD::Result
67
104
  class Error < ::StandardError
68
105
  def self.build: (**untyped) -> BCDD::Result::Error
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bcdd-result
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rodrigo Serradura
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-09-26 00:00:00.000000000 Z
11
+ date: 2023-09-27 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: A general-purpose result monad that allows you to create objects that
14
14
  represent a success (BCDD::Result::Success) or failure (BCDD::Result::Failure).
@@ -29,7 +29,9 @@ files:
29
29
  - lib/bcdd/result.rb
30
30
  - lib/bcdd/result/error.rb
31
31
  - lib/bcdd/result/failure.rb
32
+ - lib/bcdd/result/handler.rb
32
33
  - lib/bcdd/result/success.rb
34
+ - lib/bcdd/result/type.rb
33
35
  - lib/bcdd/result/version.rb
34
36
  - lib/bcdd/resultable.rb
35
37
  - sig/bcdd/result.rbs