cuprum 0.10.0 → 1.0.0.rc.1
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 +4 -4
- data/CHANGELOG.md +60 -2
- data/CODE_OF_CONDUCT.md +132 -0
- data/DEVELOPMENT.md +2 -38
- data/README.md +776 -89
- data/lib/cuprum/built_in/identity_command.rb +6 -4
- data/lib/cuprum/built_in/identity_operation.rb +4 -2
- data/lib/cuprum/built_in/null_command.rb +5 -3
- data/lib/cuprum/built_in/null_operation.rb +4 -2
- data/lib/cuprum/built_in.rb +3 -1
- data/lib/cuprum/command.rb +29 -58
- data/lib/cuprum/command_factory.rb +7 -5
- data/lib/cuprum/currying/curried_command.rb +11 -4
- data/lib/cuprum/currying.rb +3 -2
- data/lib/cuprum/error.rb +44 -10
- data/lib/cuprum/errors/command_not_implemented.rb +6 -3
- data/lib/cuprum/errors/operation_not_called.rb +6 -6
- data/lib/cuprum/errors/uncaught_exception.rb +55 -0
- data/lib/cuprum/errors.rb +2 -0
- data/lib/cuprum/exception_handling.rb +50 -0
- data/lib/cuprum/matcher.rb +90 -0
- data/lib/cuprum/matcher_list.rb +150 -0
- data/lib/cuprum/matching/match_clause.rb +65 -0
- data/lib/cuprum/matching.rb +232 -0
- data/lib/cuprum/middleware.rb +210 -0
- data/lib/cuprum/operation.rb +17 -15
- data/lib/cuprum/result.rb +1 -3
- data/lib/cuprum/rspec/be_a_result.rb +10 -1
- data/lib/cuprum/rspec/be_a_result_matcher.rb +2 -4
- data/lib/cuprum/rspec/be_callable.rb +14 -0
- data/lib/cuprum/steps.rb +45 -144
- data/lib/cuprum/utils/instance_spy.rb +28 -28
- data/lib/cuprum/utils.rb +3 -1
- data/lib/cuprum/version.rb +15 -12
- data/lib/cuprum.rb +12 -7
- metadata +33 -21
- data/lib/cuprum/chaining.rb +0 -441
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cuprum
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0.rc.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rob "Merlin" Smith
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-10-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: sleeping_king_studios-tools
|
@@ -16,70 +16,70 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '0
|
19
|
+
version: '1.0'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '0
|
26
|
+
version: '1.0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rspec
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '3.
|
33
|
+
version: '3.10'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '3.
|
40
|
+
version: '3.10'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rspec-sleeping_king_studios
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '2.
|
47
|
+
version: '2.5'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: '2.
|
54
|
+
version: '2.5'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: rubocop
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
59
|
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version:
|
61
|
+
version: 1.10.0
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version:
|
68
|
+
version: 1.10.0
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: rubocop-rspec
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
73
|
- - "~>"
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version: '1
|
75
|
+
version: '2.1'
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
80
|
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version: '1
|
82
|
+
version: '2.1'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: simplecov
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -94,9 +94,11 @@ dependencies:
|
|
94
94
|
- - "~>"
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '0.15'
|
97
|
-
description:
|
98
|
-
|
99
|
-
|
97
|
+
description: |-
|
98
|
+
An opinionated implementation of the Command pattern for Ruby applications.
|
99
|
+
Cuprum wraps your business logic in a consistent, object-oriented interface
|
100
|
+
and features status and error management, composability and control flow
|
101
|
+
management.
|
100
102
|
email:
|
101
103
|
- merlin@sleepingkingstudios.com
|
102
104
|
executables: []
|
@@ -104,6 +106,7 @@ extensions: []
|
|
104
106
|
extra_rdoc_files: []
|
105
107
|
files:
|
106
108
|
- CHANGELOG.md
|
109
|
+
- CODE_OF_CONDUCT.md
|
107
110
|
- DEVELOPMENT.md
|
108
111
|
- LICENSE
|
109
112
|
- README.md
|
@@ -113,7 +116,6 @@ files:
|
|
113
116
|
- lib/cuprum/built_in/identity_operation.rb
|
114
117
|
- lib/cuprum/built_in/null_command.rb
|
115
118
|
- lib/cuprum/built_in/null_operation.rb
|
116
|
-
- lib/cuprum/chaining.rb
|
117
119
|
- lib/cuprum/command.rb
|
118
120
|
- lib/cuprum/command_factory.rb
|
119
121
|
- lib/cuprum/currying.rb
|
@@ -122,6 +124,13 @@ files:
|
|
122
124
|
- lib/cuprum/errors.rb
|
123
125
|
- lib/cuprum/errors/command_not_implemented.rb
|
124
126
|
- lib/cuprum/errors/operation_not_called.rb
|
127
|
+
- lib/cuprum/errors/uncaught_exception.rb
|
128
|
+
- lib/cuprum/exception_handling.rb
|
129
|
+
- lib/cuprum/matcher.rb
|
130
|
+
- lib/cuprum/matcher_list.rb
|
131
|
+
- lib/cuprum/matching.rb
|
132
|
+
- lib/cuprum/matching/match_clause.rb
|
133
|
+
- lib/cuprum/middleware.rb
|
125
134
|
- lib/cuprum/operation.rb
|
126
135
|
- lib/cuprum/processing.rb
|
127
136
|
- lib/cuprum/result.rb
|
@@ -129,6 +138,7 @@ files:
|
|
129
138
|
- lib/cuprum/rspec.rb
|
130
139
|
- lib/cuprum/rspec/be_a_result.rb
|
131
140
|
- lib/cuprum/rspec/be_a_result_matcher.rb
|
141
|
+
- lib/cuprum/rspec/be_callable.rb
|
132
142
|
- lib/cuprum/steps.rb
|
133
143
|
- lib/cuprum/utils.rb
|
134
144
|
- lib/cuprum/utils/instance_spy.rb
|
@@ -136,7 +146,9 @@ files:
|
|
136
146
|
homepage: http://sleepingkingstudios.com
|
137
147
|
licenses:
|
138
148
|
- MIT
|
139
|
-
metadata:
|
149
|
+
metadata:
|
150
|
+
bug_tracker_uri: https://github.com/sleepingkingstudios/cuprum/issues
|
151
|
+
source_code_uri: https://github.com/sleepingkingstudios/cuprum
|
140
152
|
post_install_message:
|
141
153
|
rdoc_options: []
|
142
154
|
require_paths:
|
@@ -145,14 +157,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
145
157
|
requirements:
|
146
158
|
- - ">="
|
147
159
|
- !ruby/object:Gem::Version
|
148
|
-
version:
|
160
|
+
version: 2.5.0
|
149
161
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
150
162
|
requirements:
|
151
|
-
- - "
|
163
|
+
- - ">"
|
152
164
|
- !ruby/object:Gem::Version
|
153
|
-
version:
|
165
|
+
version: 1.3.1
|
154
166
|
requirements: []
|
155
|
-
rubygems_version: 3.1.
|
167
|
+
rubygems_version: 3.1.4
|
156
168
|
signing_key:
|
157
169
|
specification_version: 4
|
158
170
|
summary: An opinionated implementation of the Command pattern.
|
data/lib/cuprum/chaining.rb
DELETED
@@ -1,441 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'cuprum'
|
4
|
-
|
5
|
-
module Cuprum
|
6
|
-
# Mixin to implement command chaining functionality for a command class.
|
7
|
-
# Chaining commands allows you to define complex logic by composing it from
|
8
|
-
# simpler commands, including branching logic and error handling.
|
9
|
-
#
|
10
|
-
# @example Chaining Commands
|
11
|
-
# # By chaining commands together with the #chain instance method, we set up
|
12
|
-
# # a series of commands to run in sequence. Each chained command is passed
|
13
|
-
# # the value of the previous command.
|
14
|
-
#
|
15
|
-
# class GenerateUrlCommand
|
16
|
-
# include Cuprum::Chaining
|
17
|
-
# include Cuprum::Processing
|
18
|
-
#
|
19
|
-
# private
|
20
|
-
#
|
21
|
-
# # Acts as a pipeline, taking a value (the title of the given post) and
|
22
|
-
# # calling the underscore, URL safe, and prepend date commands. By
|
23
|
-
# # passing parameters to PrependDateCommand, we can customize the command
|
24
|
-
# # in the pipeline to the current context (in this case, the Post).
|
25
|
-
# def process post
|
26
|
-
# UnderscoreCommand.new.
|
27
|
-
# chain(UrlSafeCommand.new).
|
28
|
-
# chain(PrependDateCommand.new(post.created_at)).
|
29
|
-
# call(post.title)
|
30
|
-
# end
|
31
|
-
# end
|
32
|
-
#
|
33
|
-
# title = 'Greetings, programs!'
|
34
|
-
# date = '1982-07-09'
|
35
|
-
# post = Post.new(:title => title, :created_at => date)
|
36
|
-
# url = GenerateUrlCommand.new.call(post).value
|
37
|
-
# #=> '1982_07_09_greetings_programs'
|
38
|
-
#
|
39
|
-
# title = 'Plasma-based Einhanders in Popular Media'
|
40
|
-
# date = '1977-05-25'
|
41
|
-
# post = Post.new(:title => title, :created_at => date)
|
42
|
-
# url = GenerateUrlCommand.new.call(post).value
|
43
|
-
# #=> '1977_05_25_plasma_based_einhanders_in_popular_media'
|
44
|
-
#
|
45
|
-
# @example Conditional Chaining
|
46
|
-
# # Commands can be conditionally chained based on the success or failure of
|
47
|
-
# # the previous command using the on: keyword. If the command is chained
|
48
|
-
# # using on: :success, it will only be called if the result is passing.
|
49
|
-
# # If the command is chained using on: :failure, it will only be called if
|
50
|
-
# # the command is failing. This can be used to perform error handling.
|
51
|
-
#
|
52
|
-
# class CreateTaggingCommand
|
53
|
-
# include Cuprum::Chaining
|
54
|
-
# include Cuprum::Processing
|
55
|
-
#
|
56
|
-
# private
|
57
|
-
#
|
58
|
-
# def create_tag
|
59
|
-
# Command.new do |tag_name|
|
60
|
-
# tag = Tag.new(name: tag_name)
|
61
|
-
#
|
62
|
-
# return tag if tag.save
|
63
|
-
#
|
64
|
-
# Cuprum::Result.new(error: tag.errors)
|
65
|
-
# end
|
66
|
-
# end
|
67
|
-
#
|
68
|
-
# def create_tagging(taggable)
|
69
|
-
# Command.new do |tag|
|
70
|
-
# tagging = tag.build_tagging(taggable)
|
71
|
-
#
|
72
|
-
# return tagging if tagging.save
|
73
|
-
#
|
74
|
-
# Cuprum::Result.new(error: tagging.errors)
|
75
|
-
# end
|
76
|
-
# end
|
77
|
-
#
|
78
|
-
# def find_tag
|
79
|
-
# Command.new do |tag_name|
|
80
|
-
# tag = Tag.where(name: tag_name).first
|
81
|
-
#
|
82
|
-
# tag || Cuprum::Result.new(error: 'tag not found')
|
83
|
-
# end
|
84
|
-
# end
|
85
|
-
#
|
86
|
-
# # Tries to find the tag with the given name. If that fails, creates a
|
87
|
-
# # new tag with the given name. If the tag is found, or if the new tag is
|
88
|
-
# # successfully created, then creates a tagging using the tag. If the tag
|
89
|
-
# # is not found and cannot be created, then the tagging is not created
|
90
|
-
# # and the result of the CreateTaggingCommand is a failure with the
|
91
|
-
# # appropriate error messages.
|
92
|
-
# def process(taggable, tag_name)
|
93
|
-
# find_tag
|
94
|
-
# .chain(on: :failure) do
|
95
|
-
# # If the finding the tag fails, this step is called, returning a
|
96
|
-
# # result with a newly created tag.
|
97
|
-
# create_tag.call(tag_name)
|
98
|
-
# end
|
99
|
-
# .chain(:on => :success) do |tag|
|
100
|
-
# # Finally, the tag has been either found or created, so we can
|
101
|
-
# # create the tagging relation.
|
102
|
-
# tag.create_tagging(taggable)
|
103
|
-
# end
|
104
|
-
# .call(tag_name)
|
105
|
-
# end
|
106
|
-
# end
|
107
|
-
#
|
108
|
-
# post = Post.create(:title => 'Tagging Example')
|
109
|
-
# example_tag = Tag.create(:name => 'Example Tag')
|
110
|
-
#
|
111
|
-
# result = CreateTaggingCommand.new.call(post, 'Example Tag')
|
112
|
-
# result.success? #=> true
|
113
|
-
# result.error #=> nil
|
114
|
-
# result.value #=> an instance of Tagging
|
115
|
-
# post.tags.map(&:name)
|
116
|
-
# #=> ['Example Tag']
|
117
|
-
#
|
118
|
-
# result = CreateTaggingCommand.new.call(post, 'Another Tag')
|
119
|
-
# result.success? #=> true
|
120
|
-
# result.error #=> nil
|
121
|
-
# result.value #=> an instance of Tagging
|
122
|
-
# post.tags.map(&:name)
|
123
|
-
# #=> ['Example Tag', 'Another Tag']
|
124
|
-
#
|
125
|
-
# result = CreateTaggingCommand.new.call(post, 'An Invalid Tag Name')
|
126
|
-
# result.success? #=> false
|
127
|
-
# result.error #=> [{ tag: { name: ['is invalid'] }}]
|
128
|
-
# post.tags.map(&:name)
|
129
|
-
# #=> ['Example Tag', 'Another Tag']
|
130
|
-
#
|
131
|
-
# @example Yield Result and Tap Result
|
132
|
-
# # The #yield_result method allows for advanced control over a step in the
|
133
|
-
# # command chain. The block will be yielded the result at that point in the
|
134
|
-
# # chain, and will wrap the returned value in a result to the next chained
|
135
|
-
# # command (or return it directly if the returned value is a result).
|
136
|
-
# #
|
137
|
-
# # The #tap_result method inserts arbitrary code into the command chain
|
138
|
-
# # without interrupting it. The block will be yielded the result at that
|
139
|
-
# # point in the chain and will pass that same result to the next chained
|
140
|
-
# # command after executing the block. The return value of the block is
|
141
|
-
# # ignored.
|
142
|
-
#
|
143
|
-
# class UpdatePostCommand
|
144
|
-
# include Cuprum::Chaining
|
145
|
-
# include Cuprum::Processing
|
146
|
-
#
|
147
|
-
# private
|
148
|
-
#
|
149
|
-
# def process id, attributes
|
150
|
-
# # First, find the referenced post.
|
151
|
-
# Find.new(Post).call(id).
|
152
|
-
# yield_result(:on => :failure) do |result|
|
153
|
-
# redirect_to posts_path
|
154
|
-
# end.
|
155
|
-
# yield_result(on: :success) do |result|
|
156
|
-
# # Assign our attributes and save the post.
|
157
|
-
# UpdateAttributes.new.call(result.value, attributes)
|
158
|
-
# end.
|
159
|
-
# tap_result(:on => :success) do |result|
|
160
|
-
# # Create our tags, but still return the result of our update.
|
161
|
-
# attributes[:tags].each do |tag_name|
|
162
|
-
# CreateTaggingCommand.new.call(result.value, tag_name)
|
163
|
-
# end
|
164
|
-
# end.
|
165
|
-
# tap_result(:on => :always) do |result|
|
166
|
-
# # Chaining :on => :always ensures that the command will be run,
|
167
|
-
# # even if the previous result is failing.
|
168
|
-
# if result.failure?
|
169
|
-
# log_errors(
|
170
|
-
# :command => UpdatePostCommand,
|
171
|
-
# :error => result.error
|
172
|
-
# )
|
173
|
-
# end
|
174
|
-
# end
|
175
|
-
# end
|
176
|
-
# end
|
177
|
-
#
|
178
|
-
# @example Protected Chaining Methods
|
179
|
-
# # Using the protected chaining methods #chain!, #tap_result!, and
|
180
|
-
# # #yield_result!, you can create a command class that composes other
|
181
|
-
# # commands.
|
182
|
-
#
|
183
|
-
# # We subclass the build command, which will be executed first.
|
184
|
-
# class CreateCommentCommand < BuildCommentCommand
|
185
|
-
# include Cuprum::Chaining
|
186
|
-
# include Cuprum::Processing
|
187
|
-
#
|
188
|
-
# def initialize
|
189
|
-
# # After the build step is run, we validate the comment.
|
190
|
-
# chain!(ValidateCommentCommand.new)
|
191
|
-
#
|
192
|
-
# # If the validation passes, we then save the comment.
|
193
|
-
# chain!(SaveCommentCommand.new, on: :success)
|
194
|
-
# end
|
195
|
-
# end
|
196
|
-
#
|
197
|
-
# @see Cuprum::Command
|
198
|
-
module Chaining
|
199
|
-
# (see Cuprum::Processing#call)
|
200
|
-
def call(*args, **kwargs, &block)
|
201
|
-
yield_chain(super)
|
202
|
-
end
|
203
|
-
|
204
|
-
# Creates a copy of the first command, and then chains the given command or
|
205
|
-
# block to execute after the first command's implementation. When #call is
|
206
|
-
# executed, each chained command will be called with the previous result
|
207
|
-
# value, and its result property will be set to the previous result. The
|
208
|
-
# return value will be wrapped in a result and returned or yielded to the
|
209
|
-
# next block.
|
210
|
-
#
|
211
|
-
# @return [Cuprum::Chaining] A copy of the command, with the chained
|
212
|
-
# command.
|
213
|
-
#
|
214
|
-
# @see #yield_result
|
215
|
-
#
|
216
|
-
# @overload chain(command, on: nil)
|
217
|
-
# @param command [Cuprum::Command] The command to chain.
|
218
|
-
#
|
219
|
-
# @param on [Symbol] Sets a condition on when the chained block can run,
|
220
|
-
# based on the previous result. Valid values are :success, :failure, and
|
221
|
-
# :always. If the value is :success, the block will be called only if
|
222
|
-
# the previous result succeeded. If the value is :failure, the block
|
223
|
-
# will be called only if the previous result failed. If the value is
|
224
|
-
# :always, the block will be called regardless of the previous result
|
225
|
-
# status. If no value is given, the command will run whether the
|
226
|
-
# previous command was a success or a failure.
|
227
|
-
#
|
228
|
-
# @overload chain(on: nil) { |value| }
|
229
|
-
# Creates an anonymous command from the given block. The command will be
|
230
|
-
# passed the value of the previous result.
|
231
|
-
#
|
232
|
-
# @param on [Symbol] Sets a condition on when the chained block can run,
|
233
|
-
# based on the previous result. Valid values are :success, :failure, and
|
234
|
-
# :always. If the value is :success, the block will be called only if
|
235
|
-
# the previous result succeeded. If the value is :failure, the block
|
236
|
-
# will be called only if the previous result failed. If the value is
|
237
|
-
# :always, the block will be called regardless of the previous result
|
238
|
-
# status. If no value is given, the command will run whether the
|
239
|
-
# previous command was a success or a failure.
|
240
|
-
#
|
241
|
-
# @yieldparam value [Object] The value of the previous result.
|
242
|
-
def chain(command = nil, on: nil, &block)
|
243
|
-
clone.chain!(command, on: on, &block)
|
244
|
-
end
|
245
|
-
|
246
|
-
# As #yield_result, but always returns the previous result when the block is
|
247
|
-
# called. The return value of the block is discarded.
|
248
|
-
#
|
249
|
-
# @param (see #yield_result)
|
250
|
-
#
|
251
|
-
# @yieldparam result [Cuprum::Result] The #result of the previous command.
|
252
|
-
#
|
253
|
-
# @return (see #yield_result)
|
254
|
-
#
|
255
|
-
# @see #yield_result
|
256
|
-
def tap_result(on: nil, &block)
|
257
|
-
clone.tap_result!(on: on, &block)
|
258
|
-
end
|
259
|
-
|
260
|
-
# Creates a copy of the command, and then chains the block to execute after
|
261
|
-
# the command implementation. When #call is executed, each chained block
|
262
|
-
# will be yielded the previous result, and the return value wrapped in a
|
263
|
-
# result and returned or yielded to the next block.
|
264
|
-
#
|
265
|
-
# @param on [Symbol] Sets a condition on when the chained block can run,
|
266
|
-
# based on the previous result. Valid values are :success, :failure, and
|
267
|
-
# :always. If the value is :success, the block will be called only if the
|
268
|
-
# previous result succeeded. If the value is :failure, the block will be
|
269
|
-
# called only if the previous result failed. If the value is :always, the
|
270
|
-
# block will be called regardless of the previous result status. If no
|
271
|
-
# value is given, the command will run whether the previous command was a
|
272
|
-
# success or a failure.
|
273
|
-
#
|
274
|
-
# @yieldparam result [Cuprum::Result] The #result of the previous command.
|
275
|
-
#
|
276
|
-
# @return [Cuprum::Chaining] A copy of the command, with the chained block.
|
277
|
-
#
|
278
|
-
# @see #tap_result
|
279
|
-
def yield_result(on: nil, &block)
|
280
|
-
clone.yield_result!(on: on, &block)
|
281
|
-
end
|
282
|
-
|
283
|
-
protected
|
284
|
-
|
285
|
-
# rubocop:disable Metrics/MethodLength
|
286
|
-
|
287
|
-
# @!visibility public
|
288
|
-
#
|
289
|
-
# As #chain, but modifies the current command instead of creating a clone.
|
290
|
-
# This is a protected method, and is meant to be called by the command to be
|
291
|
-
# chained, such as during #initialize.
|
292
|
-
#
|
293
|
-
# @return [Cuprum::Chaining] The current command.
|
294
|
-
#
|
295
|
-
# @see #chain
|
296
|
-
#
|
297
|
-
# @overload chain!(command, on: nil)
|
298
|
-
# @param command [Cuprum::Command] The command to chain.
|
299
|
-
#
|
300
|
-
# @param on [Symbol] Sets a condition on when the chained block can run,
|
301
|
-
# based on the previous result. Valid values are :success, :failure, and
|
302
|
-
# :always. If the value is :success, the block will be called only if
|
303
|
-
# the previous result succeeded. If the value is :failure, the block
|
304
|
-
# will be called only if the previous result failed. If the value is
|
305
|
-
# :always, the block will be called regardless of the previous result
|
306
|
-
# status. If no value is given, the command will run whether the
|
307
|
-
# previous command was a success or a failure.
|
308
|
-
#
|
309
|
-
# @overload chain!(on: nil) { |value| }
|
310
|
-
# Creates an anonymous command from the given block. The command will be
|
311
|
-
# passed the value of the previous result.
|
312
|
-
#
|
313
|
-
# @param on [Symbol] Sets a condition on when the chained block can run,
|
314
|
-
# based on the previous result. Valid values are :success, :failure, and
|
315
|
-
# :always. If the value is :success, the block will be called only if
|
316
|
-
# the previous result succeeded. If the value is :failure, the block
|
317
|
-
# will be called only if the previous result failed. If the value is
|
318
|
-
# :always, the block will be called regardless of the previous result
|
319
|
-
# status. If no value is given, the command will run whether the
|
320
|
-
# previous command was a success or a failure.
|
321
|
-
#
|
322
|
-
# @yieldparam value [Object] The value of the previous result.
|
323
|
-
def chain!(command = nil, on: nil, &block)
|
324
|
-
SleepingKingStudios::Tools::CoreTools.deprecate(
|
325
|
-
"#{self.class}#chain",
|
326
|
-
message: 'Use the #step method to compose commands.'
|
327
|
-
)
|
328
|
-
|
329
|
-
command ||= Cuprum::Command.new(&block)
|
330
|
-
|
331
|
-
chained_procs <<
|
332
|
-
{
|
333
|
-
proc: chain_command(command),
|
334
|
-
on: on
|
335
|
-
} # end hash
|
336
|
-
|
337
|
-
self
|
338
|
-
end
|
339
|
-
# rubocop:enable Metrics/MethodLength
|
340
|
-
|
341
|
-
def chained_procs
|
342
|
-
@chained_procs ||= []
|
343
|
-
end
|
344
|
-
|
345
|
-
# rubocop:disable Metrics/MethodLength
|
346
|
-
|
347
|
-
# @!visibility public
|
348
|
-
#
|
349
|
-
# As #tap_result, but modifies the current command instead of creating a
|
350
|
-
# clone. This is a protected method, and is meant to be called by the
|
351
|
-
# command to be chained, such as during #initialize.
|
352
|
-
#
|
353
|
-
# @param (see #tap_result)
|
354
|
-
#
|
355
|
-
# @yieldparam result [Cuprum::Result] The #result of the previous command.
|
356
|
-
#
|
357
|
-
# @return (see #tap_result)
|
358
|
-
#
|
359
|
-
# @see #tap_result
|
360
|
-
def tap_result!(on: nil, &block)
|
361
|
-
SleepingKingStudios::Tools::CoreTools.deprecate(
|
362
|
-
"#{self.class}#tap_result",
|
363
|
-
message: 'Use the #step method to compose commands.'
|
364
|
-
)
|
365
|
-
|
366
|
-
tapped = ->(result) { result.tap { block.call(result) } }
|
367
|
-
|
368
|
-
chained_procs <<
|
369
|
-
{
|
370
|
-
proc: tapped,
|
371
|
-
on: on
|
372
|
-
} # end hash
|
373
|
-
|
374
|
-
self
|
375
|
-
end
|
376
|
-
# rubocop:enable Metrics/MethodLength
|
377
|
-
|
378
|
-
# @!visibility public
|
379
|
-
#
|
380
|
-
# As #yield_result, but modifies the current command instead of creating a
|
381
|
-
# clone. This is a protected method, and is meant to be called by the
|
382
|
-
# command to be chained, such as during #initialize.
|
383
|
-
#
|
384
|
-
# @param (see #yield_result)
|
385
|
-
#
|
386
|
-
# @yieldparam result [Cuprum::Result] The #result of the previous command.
|
387
|
-
#
|
388
|
-
# @return (see #yield_result)
|
389
|
-
#
|
390
|
-
# @see #yield_result
|
391
|
-
def yield_result!(on: nil, &block)
|
392
|
-
SleepingKingStudios::Tools::CoreTools.deprecate(
|
393
|
-
"#{self.class}#yield_result",
|
394
|
-
message: 'Use the #step method to compose commands.'
|
395
|
-
)
|
396
|
-
|
397
|
-
chained_procs <<
|
398
|
-
{
|
399
|
-
proc: block,
|
400
|
-
on: on
|
401
|
-
} # end hash
|
402
|
-
|
403
|
-
self
|
404
|
-
end
|
405
|
-
|
406
|
-
private
|
407
|
-
|
408
|
-
def chain_command(command)
|
409
|
-
if command.arity.zero?
|
410
|
-
->(_result) { command.call }
|
411
|
-
else
|
412
|
-
->(result) { command.call(result.value) }
|
413
|
-
end
|
414
|
-
end
|
415
|
-
|
416
|
-
def skip_chained_proc?(last_result, on:)
|
417
|
-
return false if on == :always
|
418
|
-
|
419
|
-
case on
|
420
|
-
when :success
|
421
|
-
!last_result.success?
|
422
|
-
when :failure
|
423
|
-
!last_result.failure?
|
424
|
-
end
|
425
|
-
end
|
426
|
-
|
427
|
-
def yield_chain(first_result)
|
428
|
-
chained_procs.reduce(first_result) do |result, hsh|
|
429
|
-
next result if skip_chained_proc?(result, on: hsh[:on])
|
430
|
-
|
431
|
-
value = hsh.fetch(:proc).call(result)
|
432
|
-
|
433
|
-
if value_is_result?(value)
|
434
|
-
value.to_cuprum_result
|
435
|
-
else
|
436
|
-
build_result(value: value)
|
437
|
-
end
|
438
|
-
end
|
439
|
-
end
|
440
|
-
end
|
441
|
-
end
|