param_param 0.1.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 73a3ff3dffbee8500b224cef365440d71cb01b5f8e8a8c8f0e7995e894892493
4
- data.tar.gz: c958be904a5b0794c93dbae002da9a33c10a809d168d4234beb0b184e7d2cd8f
3
+ metadata.gz: 8ef6579d2ab3739b51f2987d16d8832e5447a669c1b0fdaebefc052a86ce502d
4
+ data.tar.gz: 331d8721dbdb989c3fa7f01da832d860a34f6207be0a68601651e6ef534685cb
5
5
  SHA512:
6
- metadata.gz: da3253615f397f6bd04f080e9c9e32178bbfa1e59e193287c27ab7a81198194aece453a31fb71f4ef402d6b589da653436d79341a7d221eda838265f65ed7a28
7
- data.tar.gz: 51db488247772ae2db84f6ec5883721c9b9c7108a5596f98c98b197028bf0580cba5e1f0110ad062f035ad8802bf947ded9f47afe692df2f06b8413bc28b83df
6
+ metadata.gz: f21bfc4dfcd7fb9e3079aa9776665b408e413af23ceef696e9f06891957b0d7f7a37e8ed21449896db5a8a44ef82c9535c0ceb41a5a7ec00c3f88d8c84f6c6fe
7
+ data.tar.gz: b32827903bd128ea3477162864e39cd83eefebb57d5d08af8d3458b4880e9aab8b2560413a53b6c2d0ea231d40ba40ae0e79b7e03ae90874e59eda5393402bc7
data/README.md CHANGED
@@ -11,72 +11,67 @@ Inspired by Martin Chabot's [Simple Functional Strong Parameters In Ruby](https:
11
11
  require 'param_param'
12
12
  require 'param_param/std'
13
13
 
14
- class UserParams
14
+ class MyParams
15
15
  include ParamParam
16
16
  include ParamParam::Std
17
17
 
18
18
  # You can add your own actions
19
- capitalized = ->(option) { Success.new(Optiomist.some(option.value.capitalize)) }
20
-
21
- RULES = define.(
22
- name: required.(string.(all_of.([not_blank, max_size.(50), capitalized]))),
23
- admin: required.(bool.(any)),
24
- age: optional.(integer.(gt.(0))),
25
- )
19
+ CAPITALIZED = ->(option) { Success.new(Optiomist.some(option.value.capitalize)) }
20
+ end
26
21
 
27
- def process(params)
28
- RULES.(params)
29
- end
22
+ user_params = MyParams.define do |p|
23
+ {
24
+ name: p::REQUIRED.(p::ALL_OF.([p::STRING, p::MIN_SIZE.(1), p::MAX_SIZE.(50), p::CAPITALIZED])),
25
+ admin: p::REQUIRED.(p::BOOL),
26
+ age: p::OPTIONAL.(p::ALL_OF.([p::INTEGER, p::GT.(0)])),
27
+ }
30
28
  end
31
29
 
32
- params, errors = UserParams.new.process(
30
+ params, errors = user_params.(
33
31
  name: 'JOHN',
34
32
  admin: '0',
35
33
  age: '30',
36
34
  race: 'It is not important',
37
35
  )
36
+
38
37
  params # {:name=>"John", :admin=>false, :age=>30}
39
38
  errors # {}
40
39
 
41
40
  params, errors = UserParams.new.process(admin: 'no', age: 'very old')
42
41
  params # {:admin=>false}
43
- errors # {:name=>:missing, :age=>:non_integer}
42
+ errors # {:name=>:missing, :age=>:not_integer}
44
43
  ```
45
44
 
46
45
  ## Perform some chain of operations on provided data.
47
46
  ```
48
47
  require 'param_param'
49
48
 
49
+ require 'param_param'
50
+
50
51
  module Mather
51
52
  include ParamParam
52
53
 
53
- def self.add
54
- ->(value, option) { Success.new(Optiomist.some(option.value + value)) }.curry
55
- end
56
-
57
- def self.mul
58
- ->(value, option) { Success.new(Optiomist.some(option.value * value)) }.curry
59
- end
60
-
61
- def self.sub
62
- ->(value, option) { Success.new(Optiomist.some(option.value - value)) }.curry
63
- end
54
+ ADD = ->(value, option) { Success.new(Optiomist.some(option.value + value)) }.curry
55
+ MUL = ->(value, option) { Success.new(Optiomist.some(option.value * value)) }.curry
56
+ SUB = ->(value, option) { Success.new(Optiomist.some(option.value - value)) }.curry
64
57
  end
65
58
 
66
- rules = Mather.define.(
67
- a: Mather.add.(5),
68
- b: Mather.mul.(3),
69
- c: Mather.sub.(1),
70
- d: Mather.all_of.([Mather.add.(2), Mather.mul.(2), Mather.sub.(2)]),
71
- )
59
+ rules = Mather.define do |m|
60
+ {
61
+ a: m::ADD.(2),
62
+ b: m::MUL.(2),
63
+ c: m::SUB.(2),
64
+ d: m::ALL_OF.([m::ADD.(2), m::MUL.(2), m::SUB.(2)]),
65
+ }
66
+ end
72
67
 
73
- params, _ = rules.(
74
- a: 0,
75
- b: 1,
76
- c: 2,
77
- d: 3,
68
+ params, errors = rules.(
69
+ a: 10,
70
+ b: 10,
71
+ c: 10,
72
+ d: 10,
78
73
  )
79
74
 
80
- params # {:a=>5, :b=>3, :c=>1, :d=>8}
81
-
75
+ params # {:a=>12, :b=>20, :c=>8, :d=>22}
76
+ errors # {}
82
77
  ```
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ParamParam
4
+ # Defines actions to process hash values.
5
+ #
6
+ # An action is a lambda function assigned to a key.
7
+ # When a hash with values is provied, a value related to a key of the same name as the one the action is assigned to, processes the value.
8
+ #
9
+ # An action needs to be a lambda taking +Optiomist+ option as parameter and returning either:
10
+ # - +ParamParam::Success+ with processed option
11
+ # - +ParamParam::Failure+ with an error
12
+ #
13
+ # Example:
14
+ # actions = Actions.new(
15
+ # key: lambda { |option| option.some? ? Success.new(process(option.value)) : Failure.new(:missing) },
16
+ # ...
17
+ # )
18
+ class Actions
19
+ def initialize(actions)
20
+ @actions = actions
21
+ end
22
+
23
+ # It takes a hash and processes values related to a key by an action assigned to the same key.
24
+ #
25
+ # It returns two hashes:
26
+ # - if a value related to a key can be procesed by an action,
27
+ # the result is bound to the key and added to the first params hash
28
+ # - if a value related to a key can't be processed by an action,
29
+ # the error is bound to the key and added to the last errors hash
30
+ def call(params)
31
+ results = actions.to_h do |key, fn|
32
+ option = params.key?(key) ? optionize(params[key]) : Optiomist.none
33
+ [key, fn.call(option)]
34
+ end
35
+
36
+ errors = results.select { |_, result| result.failure? }
37
+ .transform_values(&:error)
38
+ params = results.select { |_, result| result.success? && result.value.some? }
39
+ .transform_values { |result| result.value.value }
40
+ [params, errors]
41
+ end
42
+
43
+ private
44
+
45
+ attr_reader :actions
46
+
47
+ # Converts provided value to +Optiomist::Some+.
48
+ # If the value is already +Optiomist::Some+ or +Optiomist::None+ returns it untouched.
49
+ def optionize(value)
50
+ if value.is_a?(Optiomist::Some) || value.is_a?(Optiomist::None)
51
+ value
52
+ else
53
+ Optiomist.some(value)
54
+ end
55
+ end
56
+ end
57
+ end
@@ -3,244 +3,130 @@
3
3
  module ParamParam
4
4
  # It defines some actions that can be useful in an everyday life.
5
5
  module Std
6
- def self.included(base)
7
- base.include(Messages)
8
- base.extend(Actions)
9
- end
10
-
11
6
  # Some string values that can be considered as +true+ (thank you dry-rb for inspiration).
12
7
  TRUE_VALUES = %w[1 on On ON t true True TRUE T y yes Yes YES Y].freeze
13
8
  # Some string values that can be considered as +false+ (thank you dry-rb for inspiration).
14
9
  FALSE_VALUES = %w[0 off Off OFF f false False FALSE F n no No NO N].freeze
15
10
 
16
- # Validation messages for rules.
17
- module Messages
18
- BLANK = :blank
19
- MISSING = :missing
20
-
21
- NOT_GTE = :not_gte
22
- NOT_GT = :not_gt
23
- NOT_LTE = :not_lte
24
- NOT_LT = :not_lt
25
- NOT_INCLUDED = :not_included
26
- TOO_LONG = :too_long
27
- TOO_SHORT = :too_short
28
-
29
- NON_BOOL = :non_bool
30
- NON_DECIMAL = :non_decimal
31
- NON_INTEGER = :non_integer
32
- NON_STRING = :non_string
11
+ MISSING_ERR = :missing
12
+
13
+ NOT_GTE_ERR = :not_gte
14
+ NOT_GT_ERR = :not_gt
15
+ NOT_LTE_ERR = :not_lte
16
+ NOT_LT_ERR = :not_lt
17
+ NOT_INCLUDED_ERR = :not_included
18
+ TOO_LONG_ERR = :too_long
19
+ TOO_SHORT_ERR = :too_short
20
+
21
+ NOT_BOOL_ERR = :not_bool
22
+ NOT_DECIMAL_ERR = :not_decimal
23
+ NOT_INTEGER_ERR = :not_integer
24
+ NOT_STRING_ERR = :not_string
25
+
26
+ # Verifies inclusion of a value in a collection.
27
+ #
28
+ # Verifies if value of the +option+ is included in the provided +collection+.
29
+ INCLUDED_IN = lambda do |collection, option|
30
+ collection.include?(option.value) ? Success.new(option) : Failure.new(NOT_INCLUDED_ERR)
31
+ end.curry
32
+
33
+ # Describes an optional value.
34
+ #
35
+ # If +option+ is the +Optiomist::None+ it succeeds causing the parameter not to be included in the final result.
36
+ # Otherwise executes the funciton +fn+ for the option.
37
+ OPTIONAL = lambda do |fn, option|
38
+ case option
39
+ in Optiomist::None
40
+ Success.new(option)
41
+ in Optiomist::Some
42
+ fn.call(option)
43
+ end
44
+ end.curry
45
+
46
+ # Describes a required value.
47
+ #
48
+ # It fails if +option+ is a +Optiomist::None+. Otherwise executes the funciton +fn+ for the option.
49
+ REQUIRED = lambda do |fn, option|
50
+ case option
51
+ in Optiomist::None
52
+ Failure.new(MISSING_ERR)
53
+ in Optiomist::Some
54
+ fn.call(option)
55
+ end
56
+ end.curry
57
+
58
+ # Checks if the +option+'s value is greater than or equal to the provided +limit+.
59
+ GTE = ->(limit, option) { option.value >= limit ? Success.new(option) : Failure.new(NOT_GTE_ERR) }.curry
60
+
61
+ # Checks if the +option+'s value is greater than the provided +limit+.
62
+ GT = ->(limit, option) { option.value > limit ? Success.new(option) : Failure.new(NOT_GT_ERR) }.curry
63
+
64
+ # Checks if the +option+'s value is less than or equal to the provided +limit+.
65
+ LTE = ->(limit, option) { option.value <= limit ? Success.new(option) : Failure.new(NOT_LTE_ERR) }.curry
66
+
67
+ # Checks if the +option+'s value is less than the provided +limit+.
68
+ LT = ->(limit, option) { option.value < limit ? Success.new(option) : Failure.new(NOT_LT_ERR) }.curry
69
+
70
+ # Checks if the size of the value in +option+ does not exceed provided +limit+.
71
+ MAX_SIZE = lambda do |limit, option|
72
+ option.value.size <= limit ? Success.new(option) : Failure.new(TOO_LONG_ERR)
73
+ end.curry
74
+
75
+ # Checks if the size of the value in +option+ is not lower than the provided +limit+.
76
+ MIN_SIZE = lambda do |limit, option|
77
+ option.value.size >= limit ? Success.new(option) : Failure.new(TOO_SHORT_ERR)
78
+ end.curry
79
+
80
+ # Removes leading and trailing spaces from string provided in +option+'s value.
81
+ STRIPPED = ->(option) { Success.new(Optiomist.some(option.value.strip)) }
82
+
83
+ # Converts provided +option+'s value to integer.
84
+ # If the conversion is not possible it fails.
85
+ INTEGER = lambda do |option|
86
+ begin
87
+ integer_value = Integer(option.value)
88
+ rescue StandardError
89
+ return Failure.new(NOT_INTEGER_ERR)
90
+ end
91
+ Success.new(Optiomist.some(integer_value))
33
92
  end
34
93
 
35
- # Actions definitions.
36
- module Actions
37
- # Verifies inclusion of a value in a collection.
38
- #
39
- # Returns
40
- # lambda { |collection, option| ... }.
41
- #
42
- # Verifies if value of the +option+ is included in the provided +collection+.
43
- def included_in
44
- lambda { |collection, option|
45
- collection.include?(option.value) ? Success.new(option) : Failure.new(Messages::NOT_INCLUDED)
46
- }.curry
47
- end
48
-
49
- # Describes an optional value.
50
- #
51
- # Returns
52
- # lambda { |fn, option| ... }.
53
- #
54
- # If +option+ is the +Optiomist::None+ it succeeds causing the parameter not to be included in the final result.
55
- # Otherwise executes the funciton +fn+ for the option.
56
- def optional
57
- lambda { |fn, option|
58
- case option
59
- in Optiomist::None
60
- Success.new(option)
61
- in Optiomist::Some
62
- fn.call(option)
63
- end
64
- }.curry
65
- end
66
-
67
- # Describes a required value.
68
- #
69
- # Returns
70
- # lambda { |fn, option| ... }.
71
- #
72
- # If +option+ is a +Optiomist::None+ it fails otherwise executes the funciton +fn+ for the option.
73
- def required
74
- lambda { |fn, option|
75
- case option
76
- in Optiomist::None
77
- Failure.new(Messages::MISSING)
78
- in Optiomist::Some
79
- fn.call(option)
80
- end
81
- }.curry
82
- end
83
-
84
- # Converts blank value to nil or passes non blank value to next rule.
85
- #
86
- # Returns
87
- # lambda { |fn, option| ... }.
88
- #
89
- # If provided +option+'s value is blank it succeeds with +nil+
90
- # otherwise executes provided function for the +option+.
91
- def blank_to_nil_or
92
- lambda { |fn, option|
93
- blank?(option.value) ? Success.new(Optiomist.some(nil)) : fn.call(option)
94
- }.curry
95
- end
96
-
97
- # Verifies if value is not blank.
98
- #
99
- # Returns
100
- # lambda { |option| ... }.
101
- #
102
- # It fails if provided +option+ is blank, otherwise succeeds with the +option+.
103
- def not_blank
104
- ->(option) { blank?(option.value) ? Failure.new(Messages::BLANK) : Success.new(option) }
105
- end
106
-
107
- # Verifies if provided value is nil, empty string or string consisting only from spaces.
108
- def blank?(value)
109
- value.nil? || (value.is_a?(String) && value.strip.empty?)
110
- end
111
-
112
- # Returns
113
- # lambda { |limit, option| ... }.
114
- #
115
- # Checks if the +option+'s value is greater than or equal to the provided +limit+.
116
- def gte
117
- ->(limit, option) { option.value >= limit ? Success.new(option) : Failure.new(Messages::NOT_GTE) }.curry
118
- end
119
-
120
- # Returns
121
- # lambda { |limit, option| ... }.
122
- #
123
- # Checks if the +option+'s value is greater than the provided +limit+.
124
- def gt
125
- ->(limit, option) { option.value > limit ? Success.new(option) : Failure.new(Messages::NOT_GT) }.curry
126
- end
127
-
128
- # Returns
129
- # lambda { |limit, option| ... }.
130
- #
131
- # Checks if the +option+'s value is less than or equal to the provided +limit+.
132
- def lte
133
- ->(limit, option) { option.value <= limit ? Success.new(option) : Failure.new(Messages::NOT_LTE) }.curry
134
- end
135
-
136
- # Returns
137
- # lambda { |limit, option| ... }.
138
- #
139
- # Checks if the +option+'s value is less than the provided +limit+.
140
- def lt
141
- ->(limit, option) { option.value < limit ? Success.new(option) : Failure.new(Messages::NOT_LT) }.curry
142
- end
143
-
144
- # Returns
145
- # lambda { |limit, option| ... }.
146
- #
147
- # Checks if the size of the value in +option+ does not exceed provided +limit+.
148
- def max_size
149
- lambda { |limit, option|
150
- option.value.size <= limit ? Success.new(option) : Failure.new(Messages::TOO_LONG)
151
- }.curry
152
- end
153
-
154
- # Returns
155
- # lambda { |limit, option| ... }.
156
- #
157
- # Checks if the size of the value in +option+ is not lower than the provided +limit+.
158
- def min_size
159
- lambda { |limit, option|
160
- option.value.size >= limit ? Success.new(option) : Failure.new(Messages::TOO_SHORT)
161
- }.curry
162
- end
163
-
164
- # Returns
165
- # lambda { |option| ... }.
166
- #
167
- # Removes leading and trailing spaces from string provided in +option+'s value.
168
- def stripped
169
- ->(option) { Success.new(Optiomist.some(option.value.strip)) }
170
- end
171
-
172
- # Returns
173
- # lambda { |fn, option| ... }.
174
- #
175
- # Converts provided +option+'s value to integer.
176
- # If the conversion is not possible it fails, otherwise executes the provider function +fn+
177
- # for the converted integer value.
178
- def integer
179
- lambda { |fn, option|
180
- begin
181
- integer_value = Integer(option.value)
182
- rescue StandardError
183
- return Failure.new(Messages::NON_INTEGER)
184
- end
185
- fn.call(Optiomist.some(integer_value))
186
- }.curry
187
- end
188
-
189
- # Returns
190
- # lambda { |fn, option| ... }.
191
- #
192
- # Converts provided +option+'s value to float.
193
- # If the conversion is not possible it fails, otherwise executes the provider function +fn+
194
- # for the converted float value.
195
- def decimal
196
- lambda { |fn, option|
197
- begin
198
- float_value = Float(option.value)
199
- rescue StandardError
200
- return Failure.new(Messages::NON_DECIMAL)
201
- end
202
- fn.call(Optiomist.some(float_value))
203
- }.curry
94
+ # Converts provided +option+'s value to float.
95
+ # If the conversion is not possible it fails.
96
+ DECIMAL = lambda do |option|
97
+ begin
98
+ float_value = Float(option.value)
99
+ rescue StandardError
100
+ return Failure.new(NOT_DECIMAL_ERR)
204
101
  end
102
+ Success.new(Optiomist.some(float_value))
103
+ end
205
104
 
206
- # Returns
207
- # lambda { |fn, option| ... }.
208
- #
209
- # Converts provided +option+'s value to boolean.
210
- # If the conversion is not possible it fails, otherwise executes the provider function +fn+
211
- # for the converted boolean value.
212
- def bool
213
- lambda { |fn, option|
214
- case option
215
- in Optiomist::Some
216
- if [true, *TRUE_VALUES].include?(option.value)
217
- fn.call(Optiomist.some(true))
218
- elsif [false, *FALSE_VALUES].include?(option.value)
219
- fn.call(Optiomist.some(false))
220
- else
221
- Failure.new(Messages::NON_BOOL)
222
- end
223
- in Optiomist::None
224
- Failure.new(Messages::NON_BOOL)
225
- end
226
- }.curry
105
+ # Converts provided +option+'s value to boolean.
106
+ # If the conversion is not possible it fails.
107
+ BOOL = lambda do |option|
108
+ case option
109
+ in Optiomist::Some
110
+ if [true, *TRUE_VALUES].include?(option.value)
111
+ Success.new(Optiomist.some(true))
112
+ elsif [false, *FALSE_VALUES].include?(option.value)
113
+ Success.new(Optiomist.some(false))
114
+ else
115
+ Failure.new(NOT_BOOL_ERR)
116
+ end
117
+ in Optiomist::None
118
+ Failure.new(NOT_BOOL_ERR)
227
119
  end
120
+ end
228
121
 
229
- # Returns
230
- # lambda { |fn, option| ... }.
231
- #
232
- # Converts provided +option+'s value to string.
233
- # If the conversion is not possible it fails, otherwise executes the provider function +fn+
234
- # for the converted string value.
235
- def string
236
- lambda { |fn, option|
237
- case option
238
- in Optiomist::Some
239
- fn.call(Optiomist.some(option.value.to_s))
240
- in Optiomist::None
241
- Failure.new(Messages::NON_STRING)
242
- end
243
- }.curry
122
+ # Converts provided +option+'s value to string.
123
+ # If the conversion is not possible it fails.
124
+ STRING = lambda do |option|
125
+ case option
126
+ in Optiomist::Some
127
+ Success.new(Optiomist.some(option.value.to_s))
128
+ in Optiomist::None
129
+ Failure.new(NOT_STRING_ERR)
244
130
  end
245
131
  end
246
132
  end
data/lib/param_param.rb CHANGED
@@ -2,11 +2,12 @@
2
2
 
3
3
  require 'optiomist'
4
4
  require 'param_param/result'
5
+ require 'param_param/actions'
5
6
 
6
- # It allows to define pipelines that transform hash values.
7
+ # It allows to define actions that transform hash values.
8
+ # Each actions is bound to a particular key and processes a value related to that key.
7
9
  #
8
- # Each pipeline is bound to a particular key and processes a value related to that key.
9
- # A pipeline consists of a chain of actions that are executed one by one.
10
+ # Actions could be chained and executed one by one.
10
11
  # An actions receives a value from a previous action and is expected to return successful or failed result.
11
12
  # A successful result contains a new value being the result of the processing.
12
13
  # The new value is passed further in the chain to the next action.
@@ -14,68 +15,25 @@ require 'param_param/result'
14
15
  # Following actions in the chain are not executed.
15
16
  module ParamParam
16
17
  def self.included(base)
17
- base.extend(Actions)
18
+ base.extend(ClassMethods)
18
19
  end
19
20
 
20
- # Actions definitions.
21
- module Actions
22
- # Converts provided value to +Optiomist::Some+.
23
- # If the value is already +Optiomist::Some+ or +Optiomist::None+ returns it untouched.
24
- def optionize(value)
25
- if value.is_a?(Optiomist::Some) || value.is_a?(Optiomist::None)
26
- value
27
- else
28
- Optiomist.some(value)
29
- end
30
- end
31
-
32
- # Defines pipelines and binds them to symbols.
33
- # Pipelines are used to process parameters provided in a form of a hash.
34
- # Each pipeline is defined for a key and processes a value related to that key in provided parameters.
35
- # lambda { |rules, params| ... }
36
- #
37
- # The lambda returns two hashes:
38
- # - if a value related to a key can be procesed by an action,
39
- # the result is bound to the key and added to the first hash
40
- # - if a value related to a key can't be processed by an action,
41
- # the error is bound to the key and added to the second hash
42
- #
43
- # Each action needs to be a lambda taking +Optiomist+ as the only or the last parameter and returning either:
44
- # - +ParamParam::Success+ with processed option
45
- # - +ParamParam::Failure+ with an error
46
- def define
47
- lambda { |rules, params|
48
- results = rules.to_h do |key, fn|
49
- option = params.key?(key) ? optionize(params[key]) : Optiomist.none
50
- [key, fn.call(option)]
51
- end
52
-
53
- errors = results.select { |_, result| result.failure? }
54
- .transform_values(&:error)
55
- params = results.select { |_, result| result.success? && result.value.some? }
56
- .transform_values { |result| result.value.value }
57
- [params, errors]
58
- }.curry
21
+ module ClassMethods
22
+ def define(&)
23
+ Actions.new(yield(self))
59
24
  end
25
+ end
60
26
 
61
- # It return lambda that allows defining a chain of rules that will be applied one by one
62
- # to value processed by a previous rule.
63
- #
64
- # Returns:
65
- # lambda { |fns, option| ... }
66
- # If some rule fails the chain is broken and value stops being processed.
67
- def all_of
68
- lambda { |fns, option|
69
- fns.reduce(Success.new(option)) { |result, fn| result.failure? ? result : fn.call(result.value) }
70
- }.curry
71
- end
27
+ # A chain of actions that are executed consecutively
28
+ # and pass a value from a previous action to the following one.
29
+ #
30
+ # If some action fails the chain is broken and value stops being processed.
31
+ ALL_OF = lambda do |fns, option|
32
+ fns.reduce(Success.new(option)) { |result, fn| result.failure? ? result : fn.call(result.value) }
33
+ end.curry
72
34
 
73
- # Returns
74
- # lambda { |option| ... }.
75
- #
76
- # Always succeeds with the provided +option+.
77
- def any
78
- ->(option) { Success.new(option) }
79
- end
35
+ # Always succeeds with the provided +option+.
36
+ ANY = lambda do |option|
37
+ Success.new(option)
80
38
  end
81
39
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: param_param
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michał Radmacher
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-09-21 00:00:00.000000000 Z
11
+ date: 2024-12-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: optiomist
@@ -35,6 +35,7 @@ files:
35
35
  - LICENSE
36
36
  - README.md
37
37
  - lib/param_param.rb
38
+ - lib/param_param/actions.rb
38
39
  - lib/param_param/result.rb
39
40
  - lib/param_param/std.rb
40
41
  homepage: https://github.com/mradmacher/param_param
@@ -57,8 +58,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
57
58
  - !ruby/object:Gem::Version
58
59
  version: '0'
59
60
  requirements: []
60
- rubygems_version: 3.1.2
61
+ rubygems_version: 3.4.10
61
62
  signing_key:
62
63
  specification_version: 4
63
- summary: Lambda powered pipelines for hash values
64
+ summary: Lambda powered processing of hash values
64
65
  test_files: []