bcdd-result 0.13.0 → 1.0.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.
Files changed (81) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +4 -4
  3. data/CHANGELOG.md +46 -17
  4. data/README.md +381 -220
  5. data/Rakefile +1 -1
  6. data/Steepfile +1 -1
  7. data/examples/multiple_listeners/Rakefile +8 -8
  8. data/examples/multiple_listeners/app/models/account/owner_creation.rb +1 -1
  9. data/examples/multiple_listeners/app/models/user/creation.rb +1 -1
  10. data/examples/multiple_listeners/app/models/user/token/creation.rb +1 -1
  11. data/examples/multiple_listeners/config/initializers/bcdd.rb +0 -2
  12. data/examples/multiple_listeners/config.rb +3 -3
  13. data/examples/multiple_listeners/db/setup.rb +2 -3
  14. data/examples/multiple_listeners/lib/bcdd/result/event_logs_record.rb +27 -0
  15. data/examples/multiple_listeners/lib/event_logs_listener/stdout.rb +60 -0
  16. data/examples/multiple_listeners/lib/runtime_breaker.rb +1 -1
  17. data/examples/service_objects/Rakefile +36 -0
  18. data/examples/service_objects/app/models/account/member.rb +10 -0
  19. data/examples/service_objects/app/models/account.rb +11 -0
  20. data/examples/service_objects/app/models/user/token.rb +7 -0
  21. data/examples/service_objects/app/models/user.rb +15 -0
  22. data/examples/service_objects/app/services/account/owner_creation.rb +47 -0
  23. data/examples/service_objects/app/services/application_service.rb +79 -0
  24. data/examples/service_objects/app/services/user/creation.rb +56 -0
  25. data/examples/service_objects/app/services/user/token/creation.rb +37 -0
  26. data/examples/service_objects/config/boot.rb +17 -0
  27. data/examples/service_objects/config/initializers/bcdd.rb +9 -0
  28. data/examples/service_objects/config.rb +20 -0
  29. data/examples/service_objects/db/setup.rb +49 -0
  30. data/examples/single_listener/Rakefile +5 -5
  31. data/examples/single_listener/app/models/account/owner_creation.rb +1 -1
  32. data/examples/single_listener/app/models/user/creation.rb +1 -1
  33. data/examples/single_listener/app/models/user/token/creation.rb +1 -1
  34. data/examples/single_listener/config/initializers/bcdd.rb +0 -2
  35. data/examples/single_listener/config.rb +1 -1
  36. data/examples/single_listener/lib/{single_transitions_listener.rb → single_event_logs_listener.rb} +32 -23
  37. data/lib/bcdd/{result/context → context}/callable_and_then.rb +5 -4
  38. data/lib/bcdd/{result/context → context}/expectations/mixin.rb +1 -1
  39. data/lib/bcdd/{result/context → context}/expectations.rb +2 -2
  40. data/lib/bcdd/context/failure.rb +9 -0
  41. data/lib/bcdd/{result/context → context}/mixin.rb +2 -2
  42. data/lib/bcdd/{result/context → context}/success.rb +6 -6
  43. data/lib/bcdd/context.rb +91 -0
  44. data/lib/bcdd/failure.rb +23 -0
  45. data/lib/bcdd/result/_self.rb +198 -0
  46. data/lib/bcdd/result/callable_and_then/caller.rb +1 -1
  47. data/lib/bcdd/result/config/switchers/addons.rb +2 -2
  48. data/lib/bcdd/result/config/switchers/constant_aliases.rb +1 -3
  49. data/lib/bcdd/result/config/switchers/features.rb +5 -5
  50. data/lib/bcdd/result/config/switchers/pattern_matching.rb +1 -1
  51. data/lib/bcdd/result/config.rb +7 -5
  52. data/lib/bcdd/result/contract/type_checker.rb +4 -0
  53. data/lib/bcdd/result/{transitions → event_logs}/config.rb +5 -3
  54. data/lib/bcdd/result/{transitions → event_logs}/listener.rb +5 -5
  55. data/lib/bcdd/result/{transitions → event_logs}/listeners.rb +17 -17
  56. data/lib/bcdd/result/{transitions → event_logs}/tracking/disabled.rb +1 -1
  57. data/lib/bcdd/result/{transitions → event_logs}/tracking/enabled.rb +15 -13
  58. data/lib/bcdd/result/{transitions → event_logs}/tracking.rb +4 -3
  59. data/lib/bcdd/result/{transitions → event_logs}/tree.rb +27 -11
  60. data/lib/bcdd/result/event_logs.rb +27 -0
  61. data/lib/bcdd/result/failure.rb +1 -3
  62. data/lib/bcdd/result/success.rb +1 -3
  63. data/lib/bcdd/result/version.rb +1 -1
  64. data/lib/bcdd/result.rb +23 -191
  65. data/lib/bcdd/success.rb +23 -0
  66. data/sig/bcdd/context.rbs +175 -0
  67. data/sig/bcdd/failure.rbs +13 -0
  68. data/sig/bcdd/result/config.rbs +1 -3
  69. data/sig/bcdd/result/context.rbs +2 -174
  70. data/sig/bcdd/result/contract.rbs +1 -0
  71. data/sig/bcdd/result/{transitions.rbs → event_logs.rbs} +19 -19
  72. data/sig/bcdd/result.rbs +13 -31
  73. data/sig/bcdd/success.rbs +13 -0
  74. metadata +41 -24
  75. data/examples/multiple_listeners/lib/bcdd/result/transitions_record.rb +0 -28
  76. data/examples/multiple_listeners/lib/transitions_listener/stdout.rb +0 -54
  77. data/lib/bcdd/result/context/failure.rb +0 -9
  78. data/lib/bcdd/result/context.rb +0 -93
  79. data/lib/bcdd/result/failure/methods.rb +0 -21
  80. data/lib/bcdd/result/success/methods.rb +0 -21
  81. data/lib/bcdd/result/transitions.rb +0 -27
@@ -9,8 +9,6 @@ require_relative 'config/switchers/pattern_matching'
9
9
 
10
10
  class BCDD::Result
11
11
  class Config
12
- include ::Singleton
13
-
14
12
  attr_reader :addon, :feature, :constant_alias, :pattern_matching
15
13
 
16
14
  def initialize
@@ -21,8 +19,8 @@ class BCDD::Result
21
19
  @and_then_ = CallableAndThen::Config.new
22
20
  end
23
21
 
24
- def transitions
25
- Transitions::Config.instance
22
+ def event_logs
23
+ EventLogs::Config.instance
26
24
  end
27
25
 
28
26
  def and_then!
@@ -35,7 +33,7 @@ class BCDD::Result
35
33
  constant_alias.freeze
36
34
  pattern_matching.freeze
37
35
  and_then!.freeze
38
- transitions.freeze
36
+ event_logs.freeze
39
37
 
40
38
  super
41
39
  end
@@ -58,5 +56,9 @@ class BCDD::Result
58
56
  "options=#{options.keys.sort.inspect} " \
59
57
  "and_then!=#{and_then!.options.inspect}>"
60
58
  end
59
+
60
+ @instance = new
61
+
62
+ singleton_class.send(:attr_reader, :instance)
61
63
  end
62
64
  end
@@ -10,6 +10,10 @@ module BCDD::Result::Contract
10
10
  @expectations = expectations
11
11
  end
12
12
 
13
+ def allow!(type)
14
+ expectations.type!(type)
15
+ end
16
+
13
17
  def allow?(types)
14
18
  validate(types, expected: expectations, allow_empty: false)
15
19
  end
@@ -1,9 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module BCDD::Result::Transitions
3
+ module BCDD::Result::EventLogs
4
4
  class Config
5
- include ::Singleton
6
-
7
5
  attr_reader :listener, :trace_id
8
6
 
9
7
  def initialize
@@ -22,5 +20,9 @@ module BCDD::Result::Transitions
22
20
 
23
21
  @trace_id = arg
24
22
  end
23
+
24
+ @instance = new
25
+
26
+ singleton_class.send(:attr_reader, :instance)
25
27
  end
26
28
  end
@@ -1,9 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module BCDD::Result::Transitions
3
+ module BCDD::Result::EventLogs
4
4
  module Listener
5
5
  module ClassMethods
6
- def around_transitions?
6
+ def around_event_logs?
7
7
  false
8
8
  end
9
9
 
@@ -26,7 +26,7 @@ module BCDD::Result::Transitions
26
26
 
27
27
  def on_start(scope:); end
28
28
 
29
- def around_transitions(scope:)
29
+ def around_event_logs(scope:)
30
30
  yield
31
31
  end
32
32
 
@@ -36,9 +36,9 @@ module BCDD::Result::Transitions
36
36
 
37
37
  def on_record(record:); end
38
38
 
39
- def on_finish(transitions:); end
39
+ def on_finish(event_logs:); end
40
40
 
41
- def before_interruption(exception:, transitions:); end
41
+ def before_interruption(exception:, event_logs:); end
42
42
  end
43
43
 
44
44
  module Listener::Null
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module BCDD::Result::Transitions
3
+ module BCDD::Result::EventLogs
4
4
  class Listeners
5
5
  class Chain
6
6
  include Listener
@@ -13,26 +13,26 @@ module BCDD::Result::Transitions
13
13
  end
14
14
 
15
15
  around_and_then = list.select(&:around_and_then?)
16
- around_transitions = list.select(&:around_transitions?)
16
+ around_event_logs = list.select(&:around_event_logs?)
17
17
 
18
18
  raise ArgumentError, 'only one listener can have around_and_then? == true' if around_and_then.size > 1
19
- raise ArgumentError, 'only one listener can have around_transitions? == true' if around_transitions.size > 1
19
+ raise ArgumentError, 'only one listener can have around_event_logs? == true' if around_event_logs.size > 1
20
20
 
21
- @listeners = { list: list, around_and_then: around_and_then[0], around_transitions: around_transitions[0] }
21
+ @listeners = { list: list, around_and_then: around_and_then[0], around_event_logs: around_event_logs[0] }
22
22
  end
23
23
 
24
24
  def new
25
- list, around_and_then, around_transitions = listeners[:list], nil, nil
25
+ list, around_and_then, around_event_logs = listeners[:list], nil, nil
26
26
 
27
27
  instances = list.map do |item|
28
28
  instance = item.new
29
29
  around_and_then = instance if listener?(:around_and_then, instance)
30
- around_transitions = instance if listener?(:around_transitions, instance)
30
+ around_event_logs = instance if listener?(:around_event_logs, instance)
31
31
 
32
32
  instance
33
33
  end
34
34
 
35
- list.one? ? list[0].new : Listeners.send(:new, instances, around_and_then, around_transitions)
35
+ list.one? ? list[0].new : Listeners.send(:new, instances, around_and_then, around_event_logs)
36
36
  end
37
37
 
38
38
  private
@@ -50,22 +50,22 @@ module BCDD::Result::Transitions
50
50
  Chain.new(listeners)
51
51
  end
52
52
 
53
- attr_reader :listeners, :around_and_then_listener, :around_transitions_listener
53
+ attr_reader :listeners, :around_and_then_listener, :around_event_logs_listener
54
54
 
55
- private :listeners, :around_and_then_listener, :around_transitions_listener
55
+ private :listeners, :around_and_then_listener, :around_event_logs_listener
56
56
 
57
- def initialize(listeners, around_and_then_listener, around_transitions_listener)
57
+ def initialize(listeners, around_and_then_listener, around_event_logs_listener)
58
58
  @listeners = listeners
59
59
  @around_and_then_listener = around_and_then_listener || Listener::Null
60
- @around_transitions_listener = around_transitions_listener || Listener::Null
60
+ @around_event_logs_listener = around_event_logs_listener || Listener::Null
61
61
  end
62
62
 
63
63
  def on_start(scope:)
64
64
  listeners.each { _1.on_start(scope: scope) }
65
65
  end
66
66
 
67
- def around_transitions(scope:, &block)
68
- around_transitions_listener.around_transitions(scope: scope, &block)
67
+ def around_event_logs(scope:, &block)
68
+ around_event_logs_listener.around_event_logs(scope: scope, &block)
69
69
  end
70
70
 
71
71
  def around_and_then(scope:, and_then:, &block)
@@ -76,12 +76,12 @@ module BCDD::Result::Transitions
76
76
  listeners.each { _1.on_record(record: record) }
77
77
  end
78
78
 
79
- def on_finish(transitions:)
80
- listeners.each { _1.on_finish(transitions: transitions) }
79
+ def on_finish(event_logs:)
80
+ listeners.each { _1.on_finish(event_logs: event_logs) }
81
81
  end
82
82
 
83
- def before_interruption(exception:, transitions:)
84
- listeners.each { _1.before_interruption(exception: exception, transitions: transitions) }
83
+ def before_interruption(exception:, event_logs:)
84
+ listeners.each { _1.before_interruption(exception: exception, event_logs: event_logs) }
85
85
  end
86
86
  end
87
87
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module BCDD::Result::Transitions
3
+ module BCDD::Result::EventLogs
4
4
  module Tracking::Disabled
5
5
  def self.exec(_name, _desc)
6
6
  EnsureResult[yield]
@@ -1,32 +1,32 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module BCDD::Result::Transitions
3
+ module BCDD::Result::EventLogs
4
4
  class Tracking::Enabled
5
5
  attr_accessor :tree, :records, :root_started_at, :listener
6
6
 
7
7
  private :tree, :tree=, :records, :records=, :root_started_at, :root_started_at=, :listener, :listener=
8
8
 
9
9
  def exec(name, desc)
10
- transition_node, scope = start(name, desc)
10
+ event_log_node, scope = start(name, desc)
11
11
 
12
12
  result = nil
13
13
 
14
- listener.around_transitions(scope: scope) do
14
+ listener.around_event_logs(scope: scope) do
15
15
  result = EnsureResult[yield]
16
16
  end
17
17
 
18
- tree.move_to_root! if transition_node.root?
18
+ tree.move_to_root! if event_log_node.root?
19
19
 
20
20
  finish(result)
21
21
 
22
22
  result
23
23
  rescue ::Exception => e
24
- err!(e, transition_node)
24
+ err!(e, event_log_node)
25
25
  end
26
26
 
27
- def err!(exception, transition_node)
28
- if transition_node.root?
29
- listener.before_interruption(exception: exception, transitions: map_transitions)
27
+ def err!(exception, event_log_node)
28
+ if event_log_node.root?
29
+ listener.before_interruption(exception: exception, event_logs: map_event_logs)
30
30
 
31
31
  reset!
32
32
  end
@@ -90,11 +90,11 @@ module BCDD::Result::Transitions
90
90
 
91
91
  return unless node.root?
92
92
 
93
- transitions = map_transitions
93
+ event_logs = map_event_logs
94
94
 
95
- result.send(:transitions=, transitions)
95
+ result.send(:event_logs=, event_logs)
96
96
 
97
- listener.on_finish(transitions: transitions)
97
+ listener.on_finish(event_logs: event_logs)
98
98
 
99
99
  reset!
100
100
  end
@@ -136,12 +136,14 @@ module BCDD::Result::Transitions
136
136
  ::Process.clock_gettime(::Process::CLOCK_MONOTONIC, :millisecond)
137
137
  end
138
138
 
139
- def map_transitions
139
+ def map_event_logs
140
140
  duration = (now_in_milliseconds - root_started_at)
141
141
 
142
142
  trace_id = Config.instance.trace_id.call
143
143
 
144
- metadata = { duration: duration, ids_tree: tree.nested_ids, ids_matrix: tree.ids_matrix, trace_id: trace_id }
144
+ ids = { tree: tree.ids, matrix: tree.ids_matrix, level_parent: tree.ids_level_parent }
145
+
146
+ metadata = { duration: duration, trace_id: trace_id, ids: ids }
145
147
 
146
148
  { version: Tracking::VERSION, records: records, metadata: metadata }
147
149
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class BCDD::Result
4
- module Transitions
4
+ module EventLogs
5
5
  module Tracking
6
6
  require_relative 'tracking/enabled'
7
7
  require_relative 'tracking/disabled'
@@ -11,14 +11,15 @@ class BCDD::Result
11
11
  EMPTY_ARRAY = [].freeze
12
12
  EMPTY_HASH = {}.freeze
13
13
  EMPTY_TREE = Tree.new(nil).freeze
14
+ EMPTY_IDS = { tree: EMPTY_ARRAY, matrix: EMPTY_HASH, level_parent: EMPTY_HASH }.freeze
14
15
  EMPTY = {
15
16
  version: VERSION,
16
17
  records: EMPTY_ARRAY,
17
- metadata: { duration: 0, ids_tree: EMPTY_ARRAY, ids_matrix: EMPTY_HASH, trace_id: nil }.freeze
18
+ metadata: { duration: 0, ids: EMPTY_IDS, trace_id: nil }.freeze
18
19
  }.freeze
19
20
 
20
21
  def self.instance
21
- ::BCDD::Result::Config.instance.feature.enabled?(:transitions) ? Tracking::Enabled.new : Tracking::Disabled
22
+ ::BCDD::Result::Config.instance.feature.enabled?(:event_logs) ? Tracking::Enabled.new : Tracking::Disabled
22
23
  end
23
24
  end
24
25
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class BCDD::Result
4
- module Transitions
4
+ module EventLogs
5
5
  class Tree
6
6
  class Node
7
7
  attr_reader :id, :value, :parent, :normalizer, :children
@@ -89,13 +89,17 @@ class BCDD::Result
89
89
  move_to!(root)
90
90
  end
91
91
 
92
- NestedIds = ->(node) { [node.id, node.children.map(&NestedIds)] }
92
+ Ids = ->(node) { [node.id, node.children.map(&Ids)] }
93
93
 
94
- def nested_ids
95
- NestedIds[root]
94
+ def ids
95
+ Ids[root]
96
96
  end
97
97
 
98
- IdsMatrix = ->(tree, row, col, ids, previous) do
98
+ def ids_list
99
+ ids.flatten
100
+ end
101
+
102
+ IdsMatrix = ->(tree, row, col, memo, previous) do
99
103
  last_row = previous[0]
100
104
 
101
105
  tree.each_with_index do |node, index|
@@ -103,22 +107,34 @@ class BCDD::Result
103
107
 
104
108
  id, leaf = node
105
109
 
106
- ids[id] = previous == [row, col] ? [row, col + 1] : [row, col]
110
+ memo[id] = previous == [row, col] ? [row, col + 1] : [row, col]
107
111
 
108
- previous = ids[id]
112
+ previous = memo[id]
109
113
 
110
- IdsMatrix[leaf, row, col + 1, ids, previous]
114
+ IdsMatrix[leaf, row, col + 1, memo, previous]
111
115
  end
112
116
  end
113
117
 
114
118
  def ids_matrix
115
119
  current = [0, 0]
116
120
 
117
- ids = { 0 => current }
121
+ memo = { 0 => current }
122
+
123
+ IdsMatrix[ids[1], 1, 1, memo, current]
124
+
125
+ memo
126
+ end
127
+
128
+ IdsLevelParent = ->((id, node), parent = 0, level = 0, memo = {}) do
129
+ memo[id] = [level, parent]
118
130
 
119
- IdsMatrix[nested_ids[1], 1, 1, ids, current]
131
+ node.each { |leaf| IdsLevelParent[leaf, id, level + 1, memo] }
132
+
133
+ memo
134
+ end
120
135
 
121
- ids
136
+ def ids_level_parent
137
+ IdsLevelParent[ids]
122
138
  end
123
139
  end
124
140
  end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ class BCDD::Result
4
+ module EventLogs
5
+ require_relative 'event_logs/listener'
6
+ require_relative 'event_logs/listeners'
7
+ require_relative 'event_logs/config'
8
+ require_relative 'event_logs/tree'
9
+ require_relative 'event_logs/tracking'
10
+
11
+ THREAD_VAR_NAME = :bcdd_result_event_logs_tracking
12
+
13
+ EnsureResult = ->(result) do
14
+ return result if result.is_a?(::BCDD::Result)
15
+
16
+ raise Error::UnexpectedOutcome.build(outcome: result, origin: :event_logs)
17
+ end
18
+
19
+ def self.tracking
20
+ Thread.current[THREAD_VAR_NAME] ||= Tracking.instance
21
+ end
22
+ end
23
+
24
+ def self.event_logs(name: nil, desc: nil, &block)
25
+ EventLogs.tracking.exec(name, desc, &block)
26
+ end
27
+ end
@@ -2,9 +2,7 @@
2
2
 
3
3
  class BCDD::Result
4
4
  class Failure < self
5
- require_relative 'failure/methods'
6
-
7
- include Methods
5
+ include ::BCDD::Failure
8
6
  end
9
7
 
10
8
  def self.Failure(type, value = nil)
@@ -2,9 +2,7 @@
2
2
 
3
3
  class BCDD::Result
4
4
  class Success < self
5
- require_relative 'success/methods'
6
-
7
- include Methods
5
+ include ::BCDD::Success
8
6
  end
9
7
 
10
8
  def self.Success(type, value = nil)
@@ -2,6 +2,6 @@
2
2
 
3
3
  module BCDD
4
4
  class Result
5
- VERSION = '0.13.0'
5
+ VERSION = '1.0.0'
6
6
  end
7
7
  end
data/lib/bcdd/result.rb CHANGED
@@ -1,197 +1,29 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'set'
4
- require 'singleton'
5
4
 
6
- require_relative 'result/version'
7
- require_relative 'result/error'
8
- require_relative 'result/ignored_types'
9
- require_relative 'result/transitions'
10
- require_relative 'result/callable_and_then'
11
- require_relative 'result/data'
12
- require_relative 'result/handler'
13
- require_relative 'result/failure'
14
- require_relative 'result/success'
15
- require_relative 'result/mixin'
16
- require_relative 'result/contract'
17
- require_relative 'result/expectations'
18
- require_relative 'result/context'
19
- require_relative 'result/config'
20
-
21
- class BCDD::Result
22
- attr_accessor :unknown, :transitions
23
-
24
- attr_reader :source, :data, :type_checker, :terminal
25
-
26
- protected :source
27
-
28
- private :unknown, :unknown=, :type_checker, :transitions=
29
-
30
- def self.config
31
- Config.instance
32
- end
33
-
34
- def self.configuration(freeze: true)
35
- yield(config)
36
-
37
- freeze and config.freeze
38
- end
39
-
40
- def initialize(type:, value:, source: nil, expectations: nil, terminal: nil)
41
- data = Data.new(kind, type, value)
42
-
43
- @type_checker = Contract.evaluate(data, expectations)
44
- @source = source
45
- @terminal = kind == :failure || (terminal && !IgnoredTypes.include?(type))
46
- @data = data
47
-
48
- self.unknown = true
49
- self.transitions = Transitions::Tracking::EMPTY
50
-
51
- Transitions.tracking.record(self)
52
- end
53
-
54
- def terminal?
55
- terminal
56
- end
57
-
58
- def type
59
- data.type
60
- end
61
-
62
- def value
63
- data.value
64
- end
65
-
66
- def success?(_type = nil)
67
- raise Error::NotImplemented
68
- end
69
-
70
- def failure?(_type = nil)
71
- raise Error::NotImplemented
72
- end
73
-
74
- def value_or(&_block)
75
- raise Error::NotImplemented
76
- end
77
-
78
- def on(*types, &block)
79
- raise Error::MissingTypeArgument if types.empty?
80
-
81
- tap { known(block) if type_checker.allow?(types) }
82
- end
83
-
84
- def on_success(*types, &block)
85
- tap { known(block) if type_checker.allow_success?(types) && success? }
86
- end
87
-
88
- def on_failure(*types, &block)
89
- tap { known(block) if type_checker.allow_failure?(types) && failure? }
90
- end
91
-
92
- def on_unknown
93
- tap { yield(value, type) if unknown }
94
- end
95
-
96
- def and_then(method_name = nil, injected_value = nil, &block)
97
- return self if terminal?
98
-
99
- method_name && block and raise ::ArgumentError, 'method_name and block are mutually exclusive'
100
-
101
- method_name ? call_and_then_source_method(method_name, injected_value) : call_and_then_block(block)
102
- end
103
-
104
- def and_then!(source, injected_value = nil, _call: nil)
105
- raise Error::CallableAndThenDisabled unless Config.instance.feature.enabled?(:and_then!)
106
-
107
- return self if terminal?
108
-
109
- call_and_then_callable!(source, value: value, injected_value: injected_value, method_name: _call)
110
- end
111
-
112
- def handle
113
- handler = Handler.new(self, type_checker: type_checker)
114
-
115
- yield handler
116
-
117
- handler.send(:outcome)
118
- end
119
-
120
- def ==(other)
121
- self.class == other.class && type == other.type && value == other.value
122
- end
123
-
124
- def hash
125
- [self.class, type, value].hash
126
- end
127
-
128
- def inspect
129
- format('#<%<class_name>s type=%<type>p value=%<value>p>', class_name: self.class.name, type: type, value: value)
130
- end
131
-
132
- def deconstruct
133
- [type, value]
134
- end
135
-
136
- def deconstruct_keys(_keys)
137
- { kind => { type => value } }
138
- end
139
-
140
- alias eql? ==
141
- alias on_type on
142
-
143
- private
144
-
145
- def kind
146
- :unknown
147
- end
148
-
149
- def known(block)
150
- self.unknown = false
151
-
152
- block.call(value, type)
153
- end
154
-
155
- def call_and_then_source_method(method_name, injected_value)
156
- method = source.method(method_name)
157
-
158
- Transitions.tracking.record_and_then(method, injected_value) do
159
- result = call_and_then_source_method!(method, injected_value)
160
-
161
- ensure_result_object(result, origin: :method)
162
- end
163
- end
164
-
165
- def call_and_then_source_method!(method, injected_value)
166
- case method.arity
167
- when 0 then source.send(method.name)
168
- when 1 then source.send(method.name, value)
169
- when 2 then source.send(method.name, value, injected_value)
170
- else raise Error::InvalidSourceMethodArity.build(source: source, method: method, max_arity: 2)
171
- end
172
- end
173
-
174
- def call_and_then_block(block)
175
- Transitions.tracking.record_and_then(:block, nil) do
176
- result = call_and_then_block!(block)
177
-
178
- ensure_result_object(result, origin: :block)
179
- end
180
- end
181
-
182
- def call_and_then_block!(block)
183
- block.call(value)
184
- end
185
-
186
- def call_and_then_callable!(source, value:, injected_value:, method_name:)
187
- CallableAndThen::Caller.call(source, value: value, injected_value: injected_value, method_name: method_name)
188
- end
189
-
190
- def ensure_result_object(result, origin:)
191
- raise Error::UnexpectedOutcome.build(outcome: result, origin: origin) unless result.is_a?(::BCDD::Result)
192
-
193
- return result if result.source.equal?(source)
194
-
195
- raise Error::InvalidResultSource.build(given_result: result, expected_source: source)
5
+ module BCDD
6
+ require_relative 'success'
7
+ require_relative 'failure'
8
+
9
+ class Result
10
+ require_relative 'result/version'
11
+ require_relative 'result/error'
12
+ require_relative 'result/ignored_types'
13
+ require_relative 'result/event_logs'
14
+ require_relative 'result/callable_and_then'
15
+ require_relative 'result/data'
16
+ require_relative 'result/handler'
17
+ require_relative 'result/failure'
18
+ require_relative 'result/success'
19
+ require_relative 'result/mixin'
20
+ require_relative 'result/contract'
21
+ require_relative 'result/expectations'
22
+ require_relative 'result/config'
23
+ require_relative 'result/_self'
24
+
25
+ require_relative 'context'
26
+
27
+ Context = ::BCDD::Context
196
28
  end
197
29
  end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BCDD
4
+ module Success
5
+ def success?(type = nil)
6
+ type.nil? || type_checker.allow_success?([type])
7
+ end
8
+
9
+ def failure?(_type = nil)
10
+ false
11
+ end
12
+
13
+ def value_or
14
+ value
15
+ end
16
+
17
+ private
18
+
19
+ def kind
20
+ :success
21
+ end
22
+ end
23
+ end