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 +4 -4
- data/README.md +74 -1
- data/lib/param_param/actions.rb +57 -0
- data/lib/param_param/std.rb +97 -132
- data/lib/param_param.rb +22 -140
- metadata +5 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8ef6579d2ab3739b51f2987d16d8832e5447a669c1b0fdaebefc052a86ce502d
|
4
|
+
data.tar.gz: 331d8721dbdb989c3fa7f01da832d860a34f6207be0a68601651e6ef534685cb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f21bfc4dfcd7fb9e3079aa9776665b408e413af23ceef696e9f06891957b0d7f7a37e8ed21449896db5a8a44ef82c9535c0ceb41a5a7ec00c3f88d8c84f6c6fe
|
7
|
+
data.tar.gz: b32827903bd128ea3477162864e39cd83eefebb57d5d08af8d3458b4880e9aab8b2560413a53b6c2d0ea231d40ba40ae0e79b7e03ae90874e59eda5393402bc7
|
data/README.md
CHANGED
@@ -1,4 +1,77 @@
|
|
1
1
|
# param_param
|
2
|
-
|
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
|
data/lib/param_param/std.rb
CHANGED
@@ -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
|
-
#
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
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
|
-
|
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
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
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
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
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
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
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
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
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
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
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
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
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
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
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(
|
89
|
+
return Failure.new(NOT_INTEGER_ERR)
|
107
90
|
end
|
108
|
-
|
109
|
-
|
110
|
-
end
|
91
|
+
Success.new(Optiomist.some(integer_value))
|
92
|
+
end
|
111
93
|
|
112
|
-
|
113
|
-
|
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(
|
100
|
+
return Failure.new(NOT_DECIMAL_ERR)
|
124
101
|
end
|
125
|
-
|
126
|
-
|
127
|
-
end
|
102
|
+
Success.new(Optiomist.some(float_value))
|
103
|
+
end
|
128
104
|
|
129
|
-
|
130
|
-
|
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
|
-
|
111
|
+
Success.new(Optiomist.some(true))
|
141
112
|
elsif [false, *FALSE_VALUES].include?(option.value)
|
142
|
-
|
113
|
+
Success.new(Optiomist.some(false))
|
143
114
|
else
|
144
|
-
Failure.new(
|
115
|
+
Failure.new(NOT_BOOL_ERR)
|
145
116
|
end
|
146
117
|
in Optiomist::None
|
147
|
-
Failure.new(
|
118
|
+
Failure.new(NOT_BOOL_ERR)
|
148
119
|
end
|
149
|
-
|
150
|
-
end
|
120
|
+
end
|
151
121
|
|
152
|
-
|
153
|
-
|
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
|
-
|
127
|
+
Success.new(Optiomist.some(option.value.to_s))
|
163
128
|
in Optiomist::None
|
164
|
-
Failure.new(
|
129
|
+
Failure.new(NOT_STRING_ERR)
|
165
130
|
end
|
166
|
-
|
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/
|
5
|
+
require 'param_param/actions'
|
6
6
|
|
7
|
-
#
|
8
|
-
#
|
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
|
-
#
|
11
|
-
#
|
12
|
-
#
|
13
|
-
#
|
14
|
-
#
|
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
|
-
|
34
|
-
|
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
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
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
|
-
#
|
81
|
-
#
|
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
|
-
#
|
84
|
-
|
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
|
-
|
90
|
-
end
|
33
|
+
end.curry
|
91
34
|
|
92
|
-
# Returns
|
93
|
-
# lambda { |option| ... }.
|
94
|
-
#
|
95
35
|
# Always succeeds with the provided +option+.
|
96
|
-
|
97
|
-
|
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
|
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:
|
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.
|
61
|
+
rubygems_version: 3.4.10
|
61
62
|
signing_key:
|
62
63
|
specification_version: 4
|
63
|
-
summary:
|
64
|
+
summary: Lambda powered processing of hash values
|
64
65
|
test_files: []
|