param_param 0.0.2 → 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: 61d152a83cea632bd4e660508c5dc62d26231e9bb60a35626e1991548171e205
4
- data.tar.gz: 28d02503d7fc9a374d1e555c3e9328aac9418194ed6520989165b66fe5d4a3cd
3
+ metadata.gz: 8ef6579d2ab3739b51f2987d16d8832e5447a669c1b0fdaebefc052a86ce502d
4
+ data.tar.gz: 331d8721dbdb989c3fa7f01da832d860a34f6207be0a68601651e6ef534685cb
5
5
  SHA512:
6
- metadata.gz: bdef7f585fc8f1050327bcdbe0946cc3255eca321c2f43b17fd42035cdc4d029f5d85011f91e01e2813af50b9e47ae70593f676078e483611efeed2e2a3f583b
7
- data.tar.gz: '004692833ec9cefe0d4ebdc6ec02ffa1c4de71ef38995e03aa62eecf2cbe4e8fa839f75a9119ca4adcab5576742909d69955f332f5e833c01965544fdd54c504'
6
+ metadata.gz: f21bfc4dfcd7fb9e3079aa9776665b408e413af23ceef696e9f06891957b0d7f7a37e8ed21449896db5a8a44ef82c9535c0ceb41a5a7ec00c3f88d8c84f6c6fe
7
+ data.tar.gz: b32827903bd128ea3477162864e39cd83eefebb57d5d08af8d3458b4880e9aab8b2560413a53b6c2d0ea231d40ba40ae0e79b7e03ae90874e59eda5393402bc7
data/README.md CHANGED
@@ -1,4 +1,77 @@
1
1
  # param_param
2
- Params parser built on lambdas.
2
+ Lambda powered pipelines.
3
+ Define pipelines transforming hash values.
3
4
 
4
5
  Inspired by Martin Chabot's [Simple Functional Strong Parameters In Ruby](https://blog.martinosis.com/blog/simple-functional-strong-params-in-ruby) article.
6
+
7
+ # Examples
8
+ ## Validate and transform a user provided data in a web application.
9
+
10
+ ```
11
+ require 'param_param'
12
+ require 'param_param/std'
13
+
14
+ class MyParams
15
+ include ParamParam
16
+ include ParamParam::Std
17
+
18
+ # You can add your own actions
19
+ CAPITALIZED = ->(option) { Success.new(Optiomist.some(option.value.capitalize)) }
20
+ end
21
+
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
+ }
28
+ end
29
+
30
+ params, errors = user_params.(
31
+ name: 'JOHN',
32
+ admin: '0',
33
+ age: '30',
34
+ race: 'It is not important',
35
+ )
36
+
37
+ params # {:name=>"John", :admin=>false, :age=>30}
38
+ errors # {}
39
+
40
+ params, errors = UserParams.new.process(admin: 'no', age: 'very old')
41
+ params # {:admin=>false}
42
+ errors # {:name=>:missing, :age=>:not_integer}
43
+ ```
44
+
45
+ ## Perform some chain of operations on provided data.
46
+ ```
47
+ require 'param_param'
48
+
49
+ require 'param_param'
50
+
51
+ module Mather
52
+ include ParamParam
53
+
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
57
+ end
58
+
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
67
+
68
+ params, errors = rules.(
69
+ a: 10,
70
+ b: 10,
71
+ c: 10,
72
+ d: 10,
73
+ )
74
+
75
+ params # {:a=>12, :b=>20, :c=>8, :d=>22}
76
+ errors # {}
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
@@ -1,168 +1,133 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # It contains a collection of some useful rules.
4
3
  module ParamParam
5
- # Some string values that can be considered as +true+ (thank you dry-rb for inspiration).
6
- TRUE_VALUES = %w[1 on On ON t true True TRUE T y yes Yes YES Y].freeze
7
- # Some string values that can be considered as +false+ (thank you dry-rb for inspiration).
8
- FALSE_VALUES = %w[0 off Off OFF f false False FALSE F n no No NO N].freeze
9
-
10
- NOT_GTE = :not_gte
11
- NOT_GT = :not_gt
12
- NOT_LTE = :not_lte
13
- NOT_LT = :not_lt
14
- NOT_INCLUDED = :not_included
15
- TOO_LONG = :too_long
16
- TOO_SHORT = :too_short
17
-
18
- NON_BOOL = :non_bool
19
- NON_DECIMAL = :non_decimal
20
- NON_INTEGER = :non_integer
21
- NON_STRING = :non_string
22
-
23
- # Verifies inclusion of a value in a collection.
24
- #
25
- # Returns
26
- # lambda { |collection, option| ... }.
27
- #
28
- # Verifies if value of the +option+ is included in the provided +collection+.
29
- def self.included_in
30
- lambda { |collection, option|
31
- collection.include?(option.value) ? Success.new(option) : Failure.new(NOT_INCLUDED)
32
- }.curry
33
- end
4
+ # It defines some actions that can be useful in an everyday life.
5
+ module Std
6
+ # Some string values that can be considered as +true+ (thank you dry-rb for inspiration).
7
+ TRUE_VALUES = %w[1 on On ON t true True TRUE T y yes Yes YES Y].freeze
8
+ # Some string values that can be considered as +false+ (thank you dry-rb for inspiration).
9
+ FALSE_VALUES = %w[0 off Off OFF f false False FALSE F n no No NO N].freeze
34
10
 
35
- # Returns
36
- # lambda { |limit, option| ... }.
37
- #
38
- # Checks if the +option+'s value is greater than or equal to the provided +limit+.
39
- def self.gte
40
- ->(limit, option) { option.value >= limit ? Success.new(option) : Failure.new(NOT_GTE) }.curry
41
- end
11
+ MISSING_ERR = :missing
42
12
 
43
- # Returns
44
- # lambda { |limit, option| ... }.
45
- #
46
- # Checks if the +option+'s value is greater than the provided +limit+.
47
- def self.gt
48
- ->(limit, option) { option.value > limit ? Success.new(option) : Failure.new(NOT_GT) }.curry
49
- end
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
50
20
 
51
- # Returns
52
- # lambda { |limit, option| ... }.
53
- #
54
- # Checks if the +option+'s value is less than or equal to the provided +limit+.
55
- def self.lte
56
- ->(limit, option) { option.value <= limit ? Success.new(option) : Failure.new(NOT_LTE) }.curry
57
- end
21
+ NOT_BOOL_ERR = :not_bool
22
+ NOT_DECIMAL_ERR = :not_decimal
23
+ NOT_INTEGER_ERR = :not_integer
24
+ NOT_STRING_ERR = :not_string
58
25
 
59
- # Returns
60
- # lambda { |limit, option| ... }.
61
- #
62
- # Checks if the +option+'s value is less than the provided +limit+.
63
- def self.lt
64
- ->(limit, option) { option.value < limit ? Success.new(option) : Failure.new(NOT_LT) }.curry
65
- end
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
66
32
 
67
- # Returns
68
- # lambda { |limit, option| ... }.
69
- #
70
- # Checks if the size of the value in +option+ does not exceed provided +limit+.
71
- def self.max_size
72
- lambda { |limit, option|
73
- option.value.size <= limit ? Success.new(option) : Failure.new(TOO_LONG)
74
- }.curry
75
- end
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
76
45
 
77
- # Returns
78
- # lambda { |limit, option| ... }.
79
- #
80
- # Checks if the size of the value in +option+ is not lower than the provided +limit+.
81
- def self.min_size
82
- lambda { |limit, option|
83
- option.value.size >= limit ? Success.new(option) : Failure.new(TOO_SHORT)
84
- }.curry
85
- end
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
86
57
 
87
- # Returns
88
- # lambda { |option| ... }.
89
- #
90
- # Removes leading and trailing spaces from string provided in +option+'s value.
91
- def self.stripped
92
- ->(option) { Success.new(Optiomist.some(option.value.strip)) }
93
- end
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
94
69
 
95
- # Returns
96
- # lambda { |fn, option| ... }.
97
- #
98
- # Converts provided +option+'s value to integer.
99
- # If the conversion is not possible it fails, otherwise executes the provider function +fn+
100
- # for the converted integer value.
101
- def self.integer
102
- lambda { |fn, option|
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|
103
86
  begin
104
87
  integer_value = Integer(option.value)
105
88
  rescue StandardError
106
- return Failure.new(NON_INTEGER)
89
+ return Failure.new(NOT_INTEGER_ERR)
107
90
  end
108
- fn.call(Optiomist.some(integer_value))
109
- }.curry
110
- end
91
+ Success.new(Optiomist.some(integer_value))
92
+ end
111
93
 
112
- # Returns
113
- # lambda { |fn, option| ... }.
114
- #
115
- # Converts provided +option+'s value to float.
116
- # If the conversion is not possible it fails, otherwise executes the provider function +fn+
117
- # for the converted float value.
118
- def self.decimal
119
- lambda { |fn, option|
94
+ # Converts provided +option+'s value to float.
95
+ # If the conversion is not possible it fails.
96
+ DECIMAL = lambda do |option|
120
97
  begin
121
98
  float_value = Float(option.value)
122
99
  rescue StandardError
123
- return Failure.new(NON_DECIMAL)
100
+ return Failure.new(NOT_DECIMAL_ERR)
124
101
  end
125
- fn.call(Optiomist.some(float_value))
126
- }.curry
127
- end
102
+ Success.new(Optiomist.some(float_value))
103
+ end
128
104
 
129
- # Returns
130
- # lambda { |fn, option| ... }.
131
- #
132
- # Converts provided +option+'s value to boolean.
133
- # If the conversion is not possible it fails, otherwise executes the provider function +fn+
134
- # for the converted boolean value.
135
- def self.bool
136
- lambda { |fn, option|
105
+ # Converts provided +option+'s value to boolean.
106
+ # If the conversion is not possible it fails.
107
+ BOOL = lambda do |option|
137
108
  case option
138
109
  in Optiomist::Some
139
110
  if [true, *TRUE_VALUES].include?(option.value)
140
- fn.call(Optiomist.some(true))
111
+ Success.new(Optiomist.some(true))
141
112
  elsif [false, *FALSE_VALUES].include?(option.value)
142
- fn.call(Optiomist.some(false))
113
+ Success.new(Optiomist.some(false))
143
114
  else
144
- Failure.new(NON_BOOL)
115
+ Failure.new(NOT_BOOL_ERR)
145
116
  end
146
117
  in Optiomist::None
147
- Failure.new(NON_BOOL)
118
+ Failure.new(NOT_BOOL_ERR)
148
119
  end
149
- }.curry
150
- end
120
+ end
151
121
 
152
- # Returns
153
- # lambda { |fn, option| ... }.
154
- #
155
- # Converts provided +option+'s value to string.
156
- # If the conversion is not possible it fails, otherwise executes the provider function +fn+
157
- # for the converted string value.
158
- def self.string
159
- lambda { |fn, option|
122
+ # Converts provided +option+'s value to string.
123
+ # If the conversion is not possible it fails.
124
+ STRING = lambda do |option|
160
125
  case option
161
126
  in Optiomist::Some
162
- fn.call(Optiomist.some(option.value.to_s))
127
+ Success.new(Optiomist.some(option.value.to_s))
163
128
  in Optiomist::None
164
- Failure.new(NON_STRING)
129
+ Failure.new(NOT_STRING_ERR)
165
130
  end
166
- }.curry
131
+ end
167
132
  end
168
133
  end
data/lib/param_param.rb CHANGED
@@ -2,156 +2,38 @@
2
2
 
3
3
  require 'optiomist'
4
4
  require 'param_param/result'
5
- require 'param_param/std'
5
+ require 'param_param/actions'
6
6
 
7
- # The main purpose of this module is to convert hash data
8
- # applying a chain of rules to values in the provided hash.
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.
9
9
  #
10
- # It can be used to process form data in a web application converting
11
- # user provided data to values understood by the application and validate
12
- # it the data fulfills constraints required by the application.
13
- #
14
- # Example:
15
- #
16
- # class UserOperation
17
- # Rules = ParamParam.define.(
18
- # name: ParamParam.required.(
19
- # ParamParam.string.(ParamParam.all_of.([ParamParam.not_nil, ParamParam.stripped, ParamParam.max_size.(50)]))
20
- # ),
21
- # admin: ParamParam.required.(ParamParam.bool.(ParamParam.any)),
22
- # age: ParamParam.optional.(ParamParam.integer.(ParamParam.gt.(0))),
23
- # )
24
- #
25
- # def create(name:, age:)
26
- # params, errors = Rules.(name: name, age: age)
27
- # throw errors unless errors.empty?
28
- #
29
- # # do something with params
30
- # end
31
- # end
10
+ # Actions could be chained and executed one by one.
11
+ # An actions receives a value from a previous action and is expected to return successful or failed result.
12
+ # A successful result contains a new value being the result of the processing.
13
+ # The new value is passed further in the chain to the next action.
14
+ # A failed result contains a message from an action saying why a particular value can't be processed.
15
+ # Following actions in the chain are not executed.
32
16
  module ParamParam
33
- MISSING = :missing
34
- BLANK = :blank
35
-
36
- # Converts provided value to +Optiomist::Some+.
37
- # If the value is already +Optiomist::Some+ or +Optiomist::None+ returns it untouched.
38
- def self.optionize(value)
39
- if value.is_a?(Optiomist::Some) || value.is_a?(Optiomist::None)
40
- value
41
- else
42
- Optiomist.some(value)
43
- end
44
- end
45
-
46
- # Verifies if provided value is nil, empty string or string consisting only from spaces.
47
- def self.blank?(value)
48
- value.nil? || (value.is_a?(String) && value.strip.empty?)
17
+ def self.included(base)
18
+ base.extend(ClassMethods)
49
19
  end
50
20
 
51
- # Returns lambda that allows defining a set of rules and bind them to symbols.
52
- # Later those rules can be applied to parameters provided in a for of a hash.
53
- # Each rule defined for a given key processes a value related to the same key in provided parameters.
54
- # lambda { |rules, params| ... }
55
- #
56
- # The lambda returns two hashes:
57
- # - if a value related to a key can be procesed by the rules,
58
- # the result is bound to the key and added to the first hash
59
- # - if a rule can't be applied to a value,
60
- # the error is bound to the key and added to the second hash
61
- #
62
- # Each rule needs to be a lambda taking +Optiomist+ as the only or the last parameter and returning either:
63
- # - +ParamParam::Success+ with processed option
64
- # - +ParamParam::Failure+ with an error
65
- def self.define
66
- lambda { |rules, params|
67
- results = rules.to_h do |key, fn|
68
- option = params.key?(key) ? optionize(params[key]) : Optiomist.none
69
- [key, fn.call(option)]
70
- end
71
-
72
- errors = results.select { |_, result| result.failure? }
73
- .transform_values(&:error)
74
- params = results.select { |_, result| result.success? && result.value.some? }
75
- .transform_values { |result| result.value.value }
76
- [params, errors]
77
- }.curry
21
+ module ClassMethods
22
+ def define(&)
23
+ Actions.new(yield(self))
24
+ end
78
25
  end
79
26
 
80
- # It return lambda that allows defining a chain of rules that will be applied one by one
81
- # to value processed by a previous rule.
27
+ # A chain of actions that are executed consecutively
28
+ # and pass a value from a previous action to the following one.
82
29
  #
83
- # Returns:
84
- # lambda { |fns, option| ... }
85
- # If some rule fails the chain is broken and value stops being processed.
86
- def self.all_of
87
- lambda { |fns, option|
30
+ # If some action fails the chain is broken and value stops being processed.
31
+ ALL_OF = lambda do |fns, option|
88
32
  fns.reduce(Success.new(option)) { |result, fn| result.failure? ? result : fn.call(result.value) }
89
- }.curry
90
- end
33
+ end.curry
91
34
 
92
- # Returns
93
- # lambda { |option| ... }.
94
- #
95
35
  # Always succeeds with the provided +option+.
96
- def self.any
97
- ->(option) { Success.new(option) }
98
- end
99
-
100
- # Describes an optional value.
101
- #
102
- # Returns
103
- # lambda { |fn, option| ... }.
104
- #
105
- # If +option+ is the +Optiomist::None+ it succeeds causing the parameter not to be included in the final result.
106
- # Otherwise executes the funciton +fn+ for the option.
107
- def self.optional
108
- lambda { |fn, option|
109
- case option
110
- in Optiomist::None
111
- Success.new(option)
112
- in Optiomist::Some
113
- fn.call(option)
114
- end
115
- }.curry
116
- end
117
-
118
- # Describes a required value.
119
- #
120
- # Returns
121
- # lambda { |fn, option| ... }.
122
- #
123
- # If +option+ is a +Optiomist::None+ it fails otherwise executes the funciton +fn+ for the option.
124
- def self.required
125
- lambda { |fn, option|
126
- case option
127
- in Optiomist::None
128
- Failure.new(MISSING)
129
- in Optiomist::Some
130
- fn.call(option)
131
- end
132
- }.curry
133
- end
134
-
135
- # Converts blank value to nil or passes non blank value to next rule.
136
- #
137
- # Returns
138
- # lambda { |fn, option| ... }.
139
- #
140
- # If provided +option+'s value is blank it succeeds with +nil+
141
- # otherwise executes provided function for the +option+.
142
- def self.blank_to_nil_or
143
- lambda { |fn, option|
144
- blank?(option.value) ? Success.new(Optiomist.some(nil)) : fn.call(option)
145
- }.curry
146
- end
147
-
148
- # Verifies if value is not blank.
149
- #
150
- # Returns
151
- # lambda { |option| ... }.
152
- #
153
- # It fails if provided +option+ is blank, otherwise succeeds with the +option+.
154
- def self.not_blank
155
- ->(option) { blank?(option.value) ? Failure.new(BLANK) : Success.new(option) }
36
+ ANY = lambda do |option|
37
+ Success.new(option)
156
38
  end
157
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.0.2
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-11 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.3.7
61
+ rubygems_version: 3.4.10
61
62
  signing_key:
62
63
  specification_version: 4
63
- summary: Params parser built on lambdas
64
+ summary: Lambda powered processing of hash values
64
65
  test_files: []