cuprum 1.0.0 → 1.1.0.rc.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.
@@ -24,6 +24,10 @@ module Cuprum::BuiltIn
24
24
  # result.error
25
25
  # #=> 'errors.messages.unknown'
26
26
  class IdentityCommand < Cuprum::Command
27
+ def initialize
28
+ super(&nil)
29
+ end
30
+
27
31
  private
28
32
 
29
33
  def process(value = nil)
@@ -14,15 +14,15 @@ module Cuprum::BuiltIn
14
14
  # #=> true
15
15
  #
16
16
  # @example With a result.
17
- # errors = ['errors.messages.unknown']
18
- # value = Cuprum::Result.new('result value', :errors => errors)
17
+ # error = 'errors.messages.unknown'
18
+ # value = Cuprum::Result.new(value: 'result value', error: error)
19
19
  # operation = IdentityOperation.new.call(value)
20
20
  # operation.value
21
21
  # #=> 'result value'
22
22
  # operation.success?
23
23
  # #=> false
24
- # operation.errors
25
- # #=> ['errors.messages.unknown']
24
+ # operation.error
25
+ # #=> 'errors.messages.unknown'
26
26
  class IdentityOperation < Cuprum::BuiltIn::IdentityCommand
27
27
  include Cuprum::Operation::Mixin
28
28
  end
@@ -13,8 +13,12 @@ module Cuprum::BuiltIn
13
13
  # result.success?
14
14
  # #=> true
15
15
  class NullCommand < Cuprum::Command
16
+ def initialize
17
+ super(&nil)
18
+ end
19
+
16
20
  private
17
21
 
18
- def process(*_args); end
22
+ def process(*_args, **_kwargs); end
19
23
  end
20
24
  end
@@ -5,8 +5,15 @@ require 'cuprum/processing'
5
5
  require 'cuprum/steps'
6
6
 
7
7
  module Cuprum
8
- # Functional object that encapsulates a business logic operation with a
9
- # consistent interface and tracking of result value and status.
8
+ # Functional object that encapsulates a business logic operation or step.
9
+ #
10
+ # Using commands allows the developer to maintain a state or context, such as
11
+ # by passing context into the constructor. It provides a consistent interface
12
+ # by always returning a Cuprum::Result object, which tracks the status of the
13
+ # command call, the returned value, and the error object (if any). Finally, as
14
+ # a full-fledged Ruby object a Command can be passed around like any other
15
+ # object, including returned from a method (or another Command) or passed in
16
+ # as a parameter.
10
17
  #
11
18
  # A Command can be defined either by passing a block to the constructor, or
12
19
  # by defining a subclass of Command and implementing the #process method.
@@ -19,13 +26,11 @@ module Cuprum
19
26
  #
20
27
  # @example A Command subclass
21
28
  # class MultiplyCommand < Cuprum::Command
22
- # def initialize multiplier
29
+ # def initialize(multiplier)
23
30
  # @multiplier = multiplier
24
31
  # end
25
32
  #
26
- # private
27
- #
28
- # def process int
33
+ # private def process(int)
29
34
  # int * @multiplier
30
35
  # end
31
36
  # end
@@ -37,13 +42,11 @@ module Cuprum
37
42
  #
38
43
  # @example A Command with an error state
39
44
  # class DivideCommand < Cuprum::Command
40
- # def initialize divisor
45
+ # def initialize(divisor)
41
46
  # @divisor = divisor
42
47
  # end
43
48
  #
44
- # private
45
- #
46
- # def process int
49
+ # private def process(int)
47
50
  # if @divisor.zero?
48
51
  # return Cuprum::Result.new(error: 'errors.messages.divide_by_zero')
49
52
  # end
@@ -72,10 +75,16 @@ module Cuprum
72
75
 
73
76
  # Returns a new instance of Cuprum::Command.
74
77
  #
75
- # @yield [*arguments, **keywords, &block] If a block is given, the
76
- # #call method will wrap the block and set the result #value to the return
77
- # value of the block. This overrides the implementation in #process, if
78
- # any.
78
+ # @yield If a block is given, the block is used to define a private #process
79
+ # method. This overwrites any existing #process method. When the command
80
+ # is called, #process will be called internally and passed the parameters.
81
+ #
82
+ # @yieldparam arguments [Array] the arguments passed to #call.
83
+ # @yieldparam keywords [Hash] the keywords passed to #call.
84
+ # @yieldparam block [Proc, nil] the block passed to call, #if any.
85
+ #
86
+ # @yieldreturn [Cuprum::Result, Object] the returned result or object is
87
+ # converted to a Cuprum::Result and returned by #call.
79
88
  def initialize(&implementation)
80
89
  return unless implementation
81
90
 
@@ -96,11 +105,13 @@ module Cuprum
96
105
  #
97
106
  # @return [Proc] the wrapping proc.
98
107
  def to_proc
108
+ command = self
109
+
99
110
  @to_proc ||= lambda do |*args, **kwargs, &block|
100
111
  if kwargs.empty?
101
- call(*args, &block)
112
+ command.call(*args, &block)
102
113
  else
103
- call(*args, **kwargs, &block)
114
+ command.call(*args, **kwargs, &block)
104
115
  end
105
116
  end
106
117
  end
@@ -9,11 +9,11 @@ module Cuprum
9
9
  #
10
10
  # @example
11
11
  # class SpaceFactory < Cuprum::CommandFactory
12
- # command :build, BuildCommand
12
+ # command(:build, BuildCommand)
13
13
  #
14
- # command :fly { |launch_site:| FlyCommand.new(launch_site) }
14
+ # command(:fly) { |launch_site:| FlyCommand.new(launch_site) }
15
15
  #
16
- # command_class :dream { DreamCommand }
16
+ # command_class(:dream) { DreamCommand }
17
17
  # end
18
18
  #
19
19
  # factory = SpaceFactory.new
@@ -81,7 +81,7 @@ module Cuprum
81
81
  #
82
82
  # @yield The block will be executed in the context of the factory
83
83
  # instance.
84
- # @yieldparam *args [Array] Any arguments given to the method
84
+ # @yieldparam args [Array] Any arguments given to the method
85
85
  # factory.name() will be passed on the block.
86
86
  # @yieldreturn [Cuprum::Command] The block return an instance of a
87
87
  # Cuprum::Command subclass, or else raise an error.
@@ -3,7 +3,7 @@
3
3
  require 'cuprum/currying'
4
4
 
5
5
  module Cuprum::Currying
6
- # A CurriedCommand wraps another command and passes preset args to #call.
6
+ # A CurriedCommand wraps another command and passes preset params to #call.
7
7
  #
8
8
  # @example Currying Arguments
9
9
  # # Our base command takes two arguments.
data/lib/cuprum/error.rb CHANGED
@@ -7,6 +7,48 @@ module Cuprum
7
7
  #
8
8
  # Additional details can be passed by setting the #message or by using a
9
9
  # subclass of Cuprum::Error.
10
+ #
11
+ # @example
12
+ # error = Cuprum::Error.new(message: 'Something went wrong')
13
+ # error.type
14
+ # #=> 'cuprum.error'
15
+ # error.message
16
+ # #=> 'Something went wrong'
17
+ #
18
+ # @example An Error With Custom Type
19
+ # error = Cuprum::Error.new(
20
+ # message: 'Something went wrong',
21
+ # type: 'custom.errors.generic',
22
+ # )
23
+ # error.type
24
+ # #=> 'custom.errors.generic'
25
+ #
26
+ # @example An Error Subclass
27
+ # class LightsError < Cuprum::Error
28
+ # TYPE = 'custom.errors.wrong_number_of_lights'
29
+ #
30
+ # def initialize(count)
31
+ # super(message: "There are #{count} lights!")
32
+ #
33
+ # @count = count
34
+ # end
35
+ #
36
+ # private def as_json_data
37
+ # { 'count' => count }
38
+ # end
39
+ # end
40
+ #
41
+ # error = LightsError.new(4)
42
+ # error.type
43
+ # #=> 'custom.errors.wrong_number_of_lights'
44
+ # error.message
45
+ # #=> 'There are 4 lights!'
46
+ # error.as_json
47
+ # #=> {
48
+ # # 'data' => { 'count' => 4 },
49
+ # # 'message' => 'There are 4 lights!',
50
+ # # 'type' => 'custom.errors.wrong_number_of_lights'
51
+ # # }
10
52
  class Error
11
53
  # Short string used to identify the type of error.
12
54
  #
@@ -4,14 +4,13 @@ require 'cuprum/error'
4
4
  require 'cuprum/errors'
5
5
 
6
6
  module Cuprum::Errors
7
- # Error class to be used when a Command is called without defining a #process
8
- # method.
7
+ # Error returned when a Command is called without defining a #process method.
9
8
  class CommandNotImplemented < Cuprum::Error
10
9
  COMPARABLE_PROPERTIES = %i[command].freeze
11
10
  private_constant :COMPARABLE_PROPERTIES
12
11
 
13
- # Format for generating error message.
14
12
  MESSAGE_FORMAT = 'no implementation defined for %s'
13
+ private_constant :MESSAGE_FORMAT
15
14
 
16
15
  # Short string used to identify the type of error.
17
16
  TYPE = 'cuprum.errors.command_not_implemented'
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'cuprum/error'
4
+ require 'cuprum/errors'
5
+
6
+ module Cuprum::Errors
7
+ # Error wrapping multiple errors from a collection command.
8
+ class MultipleErrors < Cuprum::Error
9
+ # Short string used to identify the type of error.
10
+ TYPE = 'cuprum.errors.multiple_errors'
11
+
12
+ # @param errors [Array<Cuprum::Error>] The wrapped errors.
13
+ # @param message [String] Optional message describing the nature of the
14
+ # error.
15
+ def initialize(errors:, message: nil)
16
+ @errors = errors
17
+
18
+ super(
19
+ errors: errors,
20
+ message: message || default_message
21
+ )
22
+ end
23
+
24
+ # @return [Array<Cuprum::Error>] the wrapped errors.
25
+ attr_reader :errors
26
+
27
+ private
28
+
29
+ def as_json_data
30
+ {
31
+ 'errors' => errors.map { |error| error&.as_json }
32
+ }
33
+ end
34
+
35
+ def default_message
36
+ 'the command encountered one or more errors'
37
+ end
38
+ end
39
+ end
@@ -4,11 +4,10 @@ require 'cuprum/error'
4
4
  require 'cuprum/errors'
5
5
 
6
6
  module Cuprum::Errors
7
- # Error class to be used when trying to access the result of an uncalled
8
- # Operation.
7
+ # Error returned when trying to access the result of an uncalled Operation.
9
8
  class OperationNotCalled < Cuprum::Error
10
- # Format for generating error message.
11
9
  MESSAGE_FORMAT = '%s was not called and does not have a result'
10
+ private_constant :MESSAGE_FORMAT
12
11
 
13
12
  # Short string used to identify the type of error.
14
13
  TYPE = 'cuprum.errors.operation_not_called'
@@ -4,7 +4,7 @@ require 'cuprum/error'
4
4
  require 'cuprum/errors'
5
5
 
6
6
  module Cuprum::Errors
7
- # An error returned when a command encounters an unhandled exception.
7
+ # Error returned when a command encounters an unhandled exception.
8
8
  class UncaughtException < Cuprum::Error
9
9
  # Short string used to identify the type of error.
10
10
  TYPE = 'cuprum.collections.errors.uncaught_exception'
@@ -45,7 +45,7 @@ module Cuprum::Errors
45
45
  end
46
46
 
47
47
  def generate_message(message)
48
- message = "#{message} #{exception.class}: #{exception.message}"
48
+ message = "#{message.rstrip} #{exception.class}: #{exception.message}"
49
49
 
50
50
  return message unless cause
51
51
 
data/lib/cuprum/errors.rb CHANGED
@@ -4,5 +4,10 @@ require 'cuprum'
4
4
 
5
5
  module Cuprum
6
6
  # Namespace for custom Cuprum error classes.
7
- module Errors; end
7
+ module Errors
8
+ autoload :CommandNotImplemented, 'cuprum/errors/command_not_implemented'
9
+ autoload :MultipleErrors, 'cuprum/errors/multiple_errors'
10
+ autoload :OperationNotCalled, 'cuprum/errors/operation_not_called'
11
+ autoload :UncaughtException, 'cuprum/errors/uncaught_exception'
12
+ end
8
13
  end
@@ -3,7 +3,7 @@
3
3
  require 'cuprum/errors/uncaught_exception'
4
4
 
5
5
  module Cuprum
6
- # Utility class for handling uncaught exceptions in commands.
6
+ # Utility module for handling uncaught exceptions in commands.
7
7
  #
8
8
  # @example
9
9
  # class UnsafeCommand < Cuprum::Command
@@ -27,7 +27,7 @@ module Cuprum
27
27
  # #=> a Cuprum::Errors::UncaughtException error.
28
28
  # result.error.message
29
29
  # #=> 'uncaught exception in SafeCommand -' \
30
- # ' StandardError: Something went wrong.'
30
+ # # ' StandardError: Something went wrong.'
31
31
  module ExceptionHandling
32
32
  # Wraps the #call method with a rescue clause matching any StandardError.
33
33
  #
@@ -37,6 +37,8 @@ module Cuprum
37
37
  #
38
38
  # @return [Cuprum::Result] the result of calling the superclass method, or
39
39
  # a failing result if a StandardError is raised.
40
+ #
41
+ # @see Cuprum::Processing#call
40
42
  def call(*args, **kwargs, &block)
41
43
  super
42
44
  rescue StandardError => exception
@@ -0,0 +1,227 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'cuprum'
4
+
5
+ module Cuprum
6
+ # Calls the command implementation with each item in the given enumerable.
7
+ #
8
+ # A regular Command is called with a set of parameters, calls the command
9
+ # implementation once with those parameters, and returns the Result. In
10
+ # contrast, a MapCommand is called with an Enumerable object, such as an
11
+ # Array, a Hash, or an Enumerator (e.g. by calling #each without a block). The
12
+ # MapCommand implementation is then called with each item in the
13
+ # Enumerable - for example, if called with an Array with three items, the
14
+ # MapCommand implementation would be called three times, once with each item.
15
+ # Finally, the Results returned by calling the implementation with each item
16
+ # are aggregated together into a Cuprum::ResultList. A ResultList behaves like
17
+ # a Result, and provides the standard methods (such as #status, #error, and
18
+ # #value), but also includes a reference to the #results used to create the
19
+ # ResultList, and their respective #errors and #values as Arrays.
20
+ #
21
+ # Like a standard Command, a MapCommand can be defined either by passing a
22
+ # block to the constructor, or by defining a subclass of MapCommand and
23
+ # implementing the #process method. If the given block or the #process method
24
+ # accepts more than one argument, the enumerable item is destructured using
25
+ # the splat operator (*); this enables using a MapCommand to map over the keys
26
+ # and values of a Hash. This is the same behavior seen when passing a block
27
+ # with multiple arguments to a native #each method.
28
+ #
29
+ # If a MapCommand is initialized with the :allow_partial keyword, the
30
+ # ResultList will be passing as long as there is at least one passing Result
31
+ # (or if the MapCommand is called with an empty Enumerable). See
32
+ # ResultList#allow_partial? for details.
33
+ #
34
+ # @example A MapCommand with a block
35
+ # titleize_command = Cuprum::MapCommand.new do |str|
36
+ # if str.nil? || str.empty?
37
+ # next failure(Cuprum::Error.new(message: "can't be blank"))
38
+ # end
39
+ #
40
+ # str.split(' ').map(&:capitalize).join(' ')
41
+ # end
42
+ #
43
+ # @example A MapCommand Subclass
44
+ # class TitleizeCommand < Cuprum::MapCommand
45
+ # private
46
+ #
47
+ # def process(str)
48
+ # if str.nil? || str.empty?
49
+ # return failure(Cuprum::Error.new(message: "can't be blank"))
50
+ # end
51
+ #
52
+ # str.split(' ').map(&:capitalize).join(' ')
53
+ # end
54
+ # end
55
+ #
56
+ # titleize_command = TitleizeCommand.new
57
+ #
58
+ # @example With an Array with passing Results
59
+ # results = titleize_command.call(['hello world', 'greetings programs'])
60
+ # results.class
61
+ # #=> Cuprum::ResultsList
62
+ # results.status
63
+ # #=> :success
64
+ # results.value
65
+ # #=> ['Hello World', 'Greetings Programs']
66
+ # results.values
67
+ # #=> ['Hello World', 'Greetings Programs']
68
+ # results.error
69
+ # #=> nil
70
+ # results.errors
71
+ # #=> [nil, nil]
72
+ #
73
+ # @example With an Array with failing Results
74
+ # results = titleize_command.call([nil, ''])
75
+ # results.status
76
+ # #=> :failure
77
+ # results.value
78
+ # #=> [nil, nil]
79
+ # results.values
80
+ # #=> [nil, nil]
81
+ # results.error.class
82
+ # #=> Cuprum::Errors::MultipleErrors
83
+ # results.errors.map(&:class)
84
+ # #=> [Cuprum::Error, Cuprum::Error]
85
+ # results.errors.first.message
86
+ # #=> "can't be blank"
87
+ #
88
+ # @example With an Array with mixed passing and failing Results
89
+ # results = titleize_command.call([nil, 'greetings programs'])
90
+ # results.status
91
+ # #=> :failure
92
+ # results.value
93
+ # #=> [nil, "Greetings Programs"]
94
+ # results.values
95
+ # #=> [nil, "Greetings Programs"]
96
+ # results.error.class
97
+ # #=> Cuprum::Errors::MultipleErrors
98
+ # results.errors.map(&:class)
99
+ # #=> [Cuprum::Error, nil]
100
+ # results.errors.first.message
101
+ # #=> "can't be blank"
102
+ #
103
+ # @example With an Empty Array
104
+ # results = titleize_command.call([])
105
+ # results.status
106
+ # #=> :success
107
+ # results.value
108
+ # #=> []
109
+ # results.values
110
+ # #=> []
111
+ # results.error
112
+ # #=> nil
113
+ # results.errors
114
+ # #=> []
115
+ #
116
+ # @example With a Hash
117
+ # inspect_command = Cuprum::MapCommand.new do |key, value|
118
+ # "#{key.inspect} => #{value.inspect}"
119
+ # end
120
+ #
121
+ # results = inspect_command.call({ ichi: 1, "ni" => 2 })
122
+ # results.status
123
+ # #=> :success
124
+ # results.value
125
+ # #=> [':ichi => 1', '"ni" => 2']
126
+ # results.values
127
+ # #=> [':ichi => 1', '"ni" => 2']
128
+ # results.error
129
+ # #=> nil
130
+ # results.errors
131
+ # #=> [nil, nil]
132
+ #
133
+ # @example With an Enumerable
134
+ # square_command = Cuprum::MapCommand.new { |i| i ** 2 }
135
+ #
136
+ # results = square_command.call(0...4)
137
+ # results.status
138
+ # #=> :success
139
+ # results.value
140
+ # #=> [0, 1, 4, 9]
141
+ # results.values
142
+ # #=> [0, 1, 4, 9]
143
+ #
144
+ # @example With allow_partial: true
145
+ # maybe_upcase_command = Cuprum::MapCommand.new do |str|
146
+ # next str.upcase if str.is_a?(String)
147
+ #
148
+ # failure(Cuprum::Error.new(message: 'not a String'))
149
+ # end
150
+ #
151
+ # results = maybe_upcase_command.call([nil, 'greetings', 'programs'])
152
+ # results.status
153
+ # #=> :success
154
+ # results.value
155
+ # #=> [nil, 'GREETINGS', 'PROGRAMS']
156
+ # results.values
157
+ # #=> [nil, 'GREETINGS', 'PROGRAMS']
158
+ # results.error.class
159
+ # #=> Cuprum::Errors::MultipleErrors
160
+ # results.errors.map(&:class)
161
+ # #=> [Cuprum::Error, nil, nil]
162
+ # results.errors.first.message
163
+ # #=> 'not a String'
164
+ #
165
+ # @see Cuprum::Command
166
+ # @see Cuprum::ResultList
167
+ class MapCommand < Cuprum::Command
168
+ # @overload initialize(allow_partial: false)
169
+ # @param allow_partial [true, false] If true, allows for some failing
170
+ # results as long as there is at least one passing result. Defaults to
171
+ # false.
172
+ #
173
+ # @overload initialize(allow_partial: false) { |item| }
174
+ # @param allow_partial [true, false] If true, allows for some failing
175
+ # results as long as there is at least one passing result. Defaults to
176
+ # false.
177
+ # @yield The command implementation, to be called with each successive
178
+ # item in the given enumerable. This overrides the #process method, if
179
+ # any.
180
+ # @yieldparam [Object] item Each item in the given Enumerable.
181
+ #
182
+ # @overload initialize(allow_partial: false) { |key, value| }
183
+ # @param allow_partial [true, false] If true, allows for some failing
184
+ # results as long as there is at least one passing result. Defaults to
185
+ # false.
186
+ # @yield The command implementation, to be called with each successive
187
+ # item in the given enumerable. This overrides the #process method, if
188
+ # any.
189
+ # @yieldparam [Object] key Each key in the given Hash.
190
+ # @yieldparam [Object] value Each value in the given Hash.
191
+ def initialize(allow_partial: false, &implementation)
192
+ super(&implementation)
193
+
194
+ @allow_partial = allow_partial
195
+ end
196
+
197
+ # @return [true, false] if true, allows for some failing results as long as
198
+ # there is at least one passing result. Defaults to false.
199
+ def allow_partial?
200
+ @allow_partial
201
+ end
202
+
203
+ # Calls the command implementation for each item in the given Enumerable.
204
+ #
205
+ # @param enumerable [Array, Hash, Enumerable] The collection or enumerable
206
+ # object to map.
207
+ #
208
+ # @return [Cuprum::ResultList] the aggregated results.
209
+ def call(enumerable)
210
+ build_result_list(
211
+ enumerable.map { |item| splat_items? ? super(*item) : super(item) }
212
+ )
213
+ end
214
+
215
+ private
216
+
217
+ def build_result_list(results)
218
+ Cuprum::ResultList.new(*results, allow_partial: allow_partial?)
219
+ end
220
+
221
+ def splat_items?
222
+ return @splat_items unless @splat_items.nil?
223
+
224
+ @splat_items = method(:process).arity > 1
225
+ end
226
+ end
227
+ end
@@ -63,6 +63,8 @@ module Cuprum
63
63
  class Matcher
64
64
  include Cuprum::Matching
65
65
 
66
+ # @!parse extend Cuprum::Matching::ClassMethods
67
+
66
68
  # @param match_context [Object] the execution context for a matching clause.
67
69
  #
68
70
  # @yield Executes the block in the context of the singleton class. This is
@@ -76,10 +76,10 @@ module Cuprum
76
76
  #
77
77
  # @param result [Cuprum::Result] The result to match.
78
78
  #
79
- # @raise Cuprum::Matching::NoMatchError if none of the matchers match the
79
+ # @raise [Cuprum::Matching::NoMatchError] if none of the matchers match the
80
80
  # given result.
81
81
  #
82
- # @see Cuprum::Matcher#call.
82
+ # @see Cuprum::Matching#call.
83
83
  def call(result)
84
84
  unless result.respond_to?(:to_cuprum_result)
85
85
  raise ArgumentError, 'result must be a Cuprum::Result'
@@ -114,6 +114,8 @@ module Cuprum
114
114
  end
115
115
  end
116
116
 
117
+ # @!parse extend ClassMethods
118
+
117
119
  # @return [Object, nil] the execution context for a matching clause.
118
120
  attr_reader :match_context
119
121
 
@@ -164,7 +166,7 @@ module Cuprum
164
166
  #
165
167
  # @raise [NoMatchError] if there is no clause matching the result.
166
168
  #
167
- # @see ClassMethods::match
169
+ # @see ClassMethods#match
168
170
  # @see #match_context
169
171
  def call(result)
170
172
  unless result.respond_to?(:to_cuprum_result)
@@ -62,7 +62,7 @@ module Cuprum
62
62
  # end
63
63
  # end
64
64
  #
65
- # command = Command.new { |**opts| "Called with #{opts.inspect}" }
65
+ # command = ExampleCommand.new
66
66
  # middleware = LoggingMiddleware.new
67
67
  # result = middleware.call(command, { id: 0 })
68
68
  # #=> logs "Calling command ExampleCommand"
@@ -81,8 +81,8 @@ module Cuprum
81
81
  # end
82
82
  # end
83
83
  #
84
- # command = Command.new { |**opts| "Called with #{opts.inspect}" }
85
- # middleware = LoggingMiddleware.new
84
+ # command = Command.new { |**options| "Options: #{options.inspect}" }
85
+ # middleware = ApiMiddleware.new
86
86
  # result = middleware.call(command, { id: 0 })
87
87
  # result.value
88
88
  # #=> "Options: { id: 0, api_key: '12345' }"
@@ -92,8 +92,8 @@ module Cuprum
92
92
  # include Cuprum::Middleware
93
93
  #
94
94
  # # The middleware runs the command once. On a failing result, the
95
- # # middleware discards the failing result and returns a result with a
96
- # # value of nil.
95
+ # # middleware discards the failing result and returns a passing result
96
+ # # with a value of nil.
97
97
  # private def process(next_command, *args, **kwargs)
98
98
  # result = super
99
99
  #
@@ -103,16 +103,23 @@ module Cuprum
103
103
  # end
104
104
  # end
105
105
  #
106
- # command = Command.new { |**opts| "Called with #{opts.inspect}" }
107
- # middleware = LoggingMiddleware.new
108
- # result = middleware.call(command, { id: 0 })
106
+ # middleware = IgnoreFailure.new
107
+ # command = Command.new do |number|
108
+ # return success('number is even') if number.even?
109
+ #
110
+ # error = Cuprum::Error.new(message: 'number is odd')
111
+ # failure(error)
112
+ # end
113
+ #
114
+ # # Calling the command without the middleware.
115
+ # result = command.call(1)
109
116
  # result.success?
110
- # #=> true
111
- # result.value
112
- # #=> "Options: { id: 0, api_key: '12345' }"
117
+ # #=> false
118
+ # result.error.message
119
+ # #=> 'number is odd'
113
120
  #
114
- # error = Cuprum::Error.new(message: 'Something went wrong.')
115
- # result = middleware.call(command, error: error)
121
+ # # Calling the command with the middleware.
122
+ # result = middleware.call(command, 1)
116
123
  # result.success?
117
124
  # #=> true
118
125
  # result.value