datacaster 3.1.2 → 3.1.5
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 +43 -11
- data/lib/datacaster/config.rb +8 -11
- data/lib/datacaster/predefined.rb +111 -79
- data/lib/datacaster/switch_node.rb +15 -10
- data/lib/datacaster/utils.rb +6 -0
- data/lib/datacaster/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 29c3f6c825f2c2d9a664e370079cde58df4ce9685d34d8428fb29aa7b98c52f3
|
|
4
|
+
data.tar.gz: 7d90ad442a4bd32ae4526d403629676c3aec9566973486bacd6565e8cb3d7bbd
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: acc11fefd17414ba1400bd98d2105b194301ac63f4d6b4204f001f918984326ab711c92d89133b475fd09d51b10c5d6427f6d6f516742a4ceb0a3eb2cf07f983
|
|
7
|
+
data.tar.gz: 07f288ab4e44e0b7a931aa43b34bac1a98d34d68f9d72241fc34f1648aeedc0412b51bdbe1113d9c34674a283e5fc6c559d4d2c5c385f5ec55c65d3b8345fb73
|
data/README.md
CHANGED
|
@@ -34,13 +34,14 @@ It is currently used in production in several projects (mainly as request parame
|
|
|
34
34
|
- [Special types](#special-types)
|
|
35
35
|
- [`absent(error_key = nil, on: nil)`](#absenterror_key--nil-on-nil)
|
|
36
36
|
- [`any(error_key = nil)`](#anyerror_key--nil)
|
|
37
|
+
- [`attribute(*keys)`](#attributekeys)
|
|
37
38
|
- [`default(default_value, on: nil)`](#defaultdefault_value-on-nil)
|
|
38
39
|
- [`merge_message_keys(*keys)`](#merge_message_keyskeys)
|
|
39
40
|
- [`must_be(klass, error_key = nil)`](#must_beklass-error_key--nil)
|
|
40
41
|
- [`optional(base, on: nil)`](#optionalbase-on-nil)
|
|
41
42
|
- [`pass`](#pass)
|
|
42
43
|
- [`pass_if(base)`](#pass_ifbase)
|
|
43
|
-
- [`pick(
|
|
44
|
+
- [`pick(*keys)`](#pickkeys)
|
|
44
45
|
- [`remove`](#remove)
|
|
45
46
|
- [`responds_to(method, error_key = nil)`](#responds_tomethod-error_key--nil)
|
|
46
47
|
- [`transform_to_value(value)`](#transform_to_valuevalue)
|
|
@@ -414,6 +415,7 @@ Notice that shortcut definitions are available (illustrated in the example above
|
|
|
414
415
|
|
|
415
416
|
* `switch(:key)` is exactly the same as `switch(pick(:key))` (works for a string, a symbol, or an array thereof)
|
|
416
417
|
* `on(:key, ...)` is exactly the same as `on(compare(:key), ...)` (works for a string or a symbol)
|
|
418
|
+
* `on(:key, ...)` will match on `:key` and `'key'` value, and the same is true for `on('key', ...)` (to disable that behavior provide `strict: true` keyword arg: `on('key', ..., strict: true)`)
|
|
417
419
|
* `switch([caster], on_check => on_caster, ...)` is exactly the same as `switch([caster]).on(on_check, on_caster).on(...)`
|
|
418
420
|
|
|
419
421
|
`switch()` without a `base` argument will pass the incoming value to the `.on(...)` casters.
|
|
@@ -523,6 +525,26 @@ Returns ValidResult if and only if provided value is not `Datacaster.absent` (th
|
|
|
523
525
|
|
|
524
526
|
I18n keys: `error_key`, `'.any'`, `'datacaster.errors.any'`
|
|
525
527
|
|
|
528
|
+
#### `attribute(*keys)`
|
|
529
|
+
|
|
530
|
+
Always returns ValidResult. Calls provided method(s) (recursively) on the value and returns their results. `*keys` should be specified in exactly the same manner as in [pick](#pickkeys).
|
|
531
|
+
|
|
532
|
+
```ruby
|
|
533
|
+
class User
|
|
534
|
+
def login
|
|
535
|
+
"Alex"
|
|
536
|
+
end
|
|
537
|
+
end
|
|
538
|
+
|
|
539
|
+
login = Datacaster.schema { attribute(:login) }
|
|
540
|
+
|
|
541
|
+
# => Datacaster::ValidResult("Alex")
|
|
542
|
+
login.(User.new)
|
|
543
|
+
|
|
544
|
+
# => Datacaster::ValidResult(#<Datacaster.absent>)
|
|
545
|
+
login.("test")
|
|
546
|
+
```
|
|
547
|
+
|
|
526
548
|
#### `default(default_value, on: nil)`
|
|
527
549
|
|
|
528
550
|
Always returns ValidResult.
|
|
@@ -633,7 +655,7 @@ mapping.(
|
|
|
633
655
|
|
|
634
656
|
See also `#cast_errors` for [error remapping](#error-remapping-cast_errors).
|
|
635
657
|
|
|
636
|
-
See also `#pick` for [simpler picking of hash values](#
|
|
658
|
+
See also `#pick` for [simpler picking of hash values](#pickkeys).
|
|
637
659
|
|
|
638
660
|
I18n keys:
|
|
639
661
|
|
|
@@ -686,15 +708,18 @@ Returns ValidResult if and only if base returns ValidResult. Returns base's erro
|
|
|
686
708
|
|
|
687
709
|
Doesn't transform the value: if base succeeds returns the original value (not the one that base returned).
|
|
688
710
|
|
|
689
|
-
#### `pick(
|
|
711
|
+
#### `pick(*keys)`
|
|
690
712
|
|
|
691
713
|
Returns ValidResult if and only if the value `#is_a?(Enumerable)`.
|
|
692
714
|
|
|
693
|
-
|
|
715
|
+
Each argument should be a string, a Symbol, an integer or an array thereof. Each argument plays the role of key(s) to fetch from the value:
|
|
716
|
+
|
|
717
|
+
* If the argument is an Array, value is extracted recursively
|
|
718
|
+
* Otherwise, `value[argument]` is fetched and added to the result (or `Datacaster.absent` if is is impossible to fetch)
|
|
719
|
+
|
|
720
|
+
If only one argument is provided to the `pick`, one fetched value is returned. If several arguments are provided, array is returned wherein each value corresponds to each argument.
|
|
694
721
|
|
|
695
|
-
|
|
696
|
-
* `nil` if `value[key]` is set and is nil
|
|
697
|
-
* `Datacaster.absent` if key is not set
|
|
722
|
+
Fetching single key:
|
|
698
723
|
|
|
699
724
|
```ruby
|
|
700
725
|
pick_name = Datacaster.schema { pick(:name) }
|
|
@@ -705,9 +730,7 @@ pick_name.(last_name: "Johnson") # => Datacaster::ValidResult(#<Datacaster.absen
|
|
|
705
730
|
pick_name.("test") # => Datacaster::ErrorResult(["is not Enumerable"])
|
|
706
731
|
```
|
|
707
732
|
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
In this case, an array of results is returned, each element in which corresponds to the element in `keys` array (i.e. is an argument of the `pick`) and evaluated in accordance with the above rules.
|
|
733
|
+
Fetching multiple keys:
|
|
711
734
|
|
|
712
735
|
```ruby
|
|
713
736
|
pick_name_and_age = Datacaster.schema { pick(:name, :age) }
|
|
@@ -718,6 +741,15 @@ pick_name_and_age.(last_name: "Johnson", age: 20) # => Datacaster::ValidResult([
|
|
|
718
741
|
pick_name_and_age.("test") # => Datacaster::ErrorResult(["is not Enumerable"])
|
|
719
742
|
```
|
|
720
743
|
|
|
744
|
+
Fetching deeply nested key:
|
|
745
|
+
|
|
746
|
+
```ruby
|
|
747
|
+
nested_hash_picker = Datacaster.schema { pick([:user, :age]) }
|
|
748
|
+
|
|
749
|
+
nested_hash_picker.(user: { age: 21 }) # => Datacaster::ValidResult(21)
|
|
750
|
+
nested_hash_picker.(user: { name: "Alex" }) # => Datacaster::ValidResult(#<Datacaster.absent>)
|
|
751
|
+
```
|
|
752
|
+
|
|
721
753
|
I18n keys:
|
|
722
754
|
|
|
723
755
|
* not a Enumerable – `'.must_be'`, `'datacaster.errors.must_be'`.
|
|
@@ -1322,7 +1354,7 @@ Note: in the "root" scope (immediately inside of `schema { ... }` block) the wor
|
|
|
1322
1354
|
|
|
1323
1355
|
### Mapping hashes: `transform_to_hash`
|
|
1324
1356
|
|
|
1325
|
-
One common task in processing compound data structures is to map one set of hash keys to another set. That's where `transform_to_hash` type comes to play (see also [`pick`](#
|
|
1357
|
+
One common task in processing compound data structures is to map one set of hash keys to another set. That's where `transform_to_hash` type comes to play (see also [`pick`](#pickkeys) and [`remove`](#remove)).
|
|
1326
1358
|
|
|
1327
1359
|
```ruby
|
|
1328
1360
|
city_with_distance =
|
data/lib/datacaster/config.rb
CHANGED
|
@@ -7,17 +7,14 @@ module Datacaster
|
|
|
7
7
|
attr_accessor :i18n_module
|
|
8
8
|
|
|
9
9
|
def add_predefined_caster(name, definition)
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
Predefined.define_method(name.to_sym) { caster }
|
|
10
|
+
case definition
|
|
11
|
+
when Proc
|
|
12
|
+
Predefined.define_method(name.to_sym, &definition)
|
|
13
|
+
when Base
|
|
14
|
+
Predefined.define_method(name.to_sym) { definition }
|
|
15
|
+
else
|
|
16
|
+
raise ArgumentError.new("Expected Datacaster defintion lambda or Datacaster instance")
|
|
17
|
+
end
|
|
21
18
|
end
|
|
22
19
|
|
|
23
20
|
def i18n_t
|
|
@@ -54,15 +54,15 @@ module Datacaster
|
|
|
54
54
|
end
|
|
55
55
|
|
|
56
56
|
def schema(base)
|
|
57
|
-
ContextNodes::StructureCleaner.new(base,
|
|
57
|
+
ContextNodes::StructureCleaner.new(base, :fail)
|
|
58
58
|
end
|
|
59
59
|
|
|
60
60
|
def choosy_schema(base)
|
|
61
|
-
ContextNodes::StructureCleaner.new(base,
|
|
61
|
+
ContextNodes::StructureCleaner.new(base, :remove)
|
|
62
62
|
end
|
|
63
63
|
|
|
64
64
|
def partial_schema(base)
|
|
65
|
-
ContextNodes::StructureCleaner.new(base,
|
|
65
|
+
ContextNodes::StructureCleaner.new(base, :pass)
|
|
66
66
|
end
|
|
67
67
|
|
|
68
68
|
# 'Meta' types
|
|
@@ -89,6 +89,26 @@ module Datacaster
|
|
|
89
89
|
check { |x| x != Datacaster.absent }.i18n_key(*error_keys)
|
|
90
90
|
end
|
|
91
91
|
|
|
92
|
+
def attribute(*keys)
|
|
93
|
+
if keys.empty? || keys.any? { |k| !Datacaster::Utils.pickable?(k) }
|
|
94
|
+
raise RuntimeError, "each argument should be String, Symbol, Integer or an array thereof", caller
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
transform do |input|
|
|
98
|
+
result =
|
|
99
|
+
keys.map do |key|
|
|
100
|
+
Array(key).reduce(input) do |result, k|
|
|
101
|
+
if result.respond_to?(k)
|
|
102
|
+
result.public_send(k)
|
|
103
|
+
else
|
|
104
|
+
break Datacaster.absent
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
keys.length == 1 ? result.first : result
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
|
|
92
112
|
def default(value, on: nil)
|
|
93
113
|
transform do |x|
|
|
94
114
|
if x == Datacaster.absent ||
|
|
@@ -100,46 +120,108 @@ module Datacaster
|
|
|
100
120
|
end
|
|
101
121
|
end
|
|
102
122
|
|
|
103
|
-
def
|
|
104
|
-
|
|
123
|
+
def merge_message_keys(*keys)
|
|
124
|
+
MessageKeysMerger.new(keys)
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def must_be(klass, error_key = nil)
|
|
128
|
+
error_keys = ['.must_be', 'datacaster.errors.must_be']
|
|
129
|
+
error_keys.unshift(error_key) if error_key
|
|
130
|
+
check { |x| x.is_a?(klass) }.i18n_key(*error_keys, reference: klass.name)
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
def optional(base, on: nil)
|
|
134
|
+
return absent | base if on == nil
|
|
135
|
+
cast do |x|
|
|
136
|
+
if x == Datacaster.absent ||
|
|
137
|
+
(!on.nil? && x.respond_to?(on) && x.public_send(on))
|
|
138
|
+
Datacaster.ValidResult(Datacaster.absent)
|
|
139
|
+
else
|
|
140
|
+
base.(x)
|
|
141
|
+
end
|
|
142
|
+
end
|
|
105
143
|
end
|
|
106
144
|
|
|
107
|
-
|
|
145
|
+
def pass
|
|
146
|
+
transform(&:itself)
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
def pass_if(base)
|
|
150
|
+
ContextNodes::PassIf.new(base)
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
def pick(*keys)
|
|
154
|
+
if keys.empty? || keys.any? { |k| !Datacaster::Utils.pickable?(k) }
|
|
155
|
+
raise RuntimeError, "each argument should be String, Symbol, Integer or an array thereof", caller
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
retrieve_key = -> (from, key) do
|
|
159
|
+
if from.respond_to?(:key?) && !from.key?(key)
|
|
160
|
+
Datacaster.absent
|
|
161
|
+
elsif from.respond_to?(:length) && key.is_a?(Integer) && key > 0 && key >= from.length
|
|
162
|
+
Datacaster.absent
|
|
163
|
+
elsif !from.respond_to?(:[])
|
|
164
|
+
Datacaster.absent
|
|
165
|
+
else
|
|
166
|
+
from[key]
|
|
167
|
+
end
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
must_be(Enumerable) & transform { |input|
|
|
171
|
+
result =
|
|
172
|
+
keys.map do |key|
|
|
173
|
+
Array(key).reduce(input) do |result, k|
|
|
174
|
+
result = retrieve_key.(result, k)
|
|
175
|
+
break result if result == Datacaster.absent
|
|
176
|
+
result
|
|
177
|
+
end
|
|
178
|
+
end
|
|
179
|
+
keys.length == 1 ? result.first : result
|
|
180
|
+
}
|
|
181
|
+
end
|
|
108
182
|
|
|
109
183
|
def relate(left, op, right, error_key: nil)
|
|
110
184
|
error_keys = ['.relate', 'datacaster.errors.relate']
|
|
111
185
|
additional_vars = {}
|
|
112
186
|
|
|
187
|
+
left_caster = left
|
|
188
|
+
if Datacaster::Utils.pickable?(left)
|
|
189
|
+
left_caster = pick(left)
|
|
190
|
+
elsif !Datacaster.instance?(left)
|
|
191
|
+
raise RuntimeError, "provide String, Symbol, Integer or array thereof instead of #{left.inspect}", caller
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
right_caster = right
|
|
195
|
+
if Datacaster::Utils.pickable?(right)
|
|
196
|
+
right_caster = pick(right)
|
|
197
|
+
elsif !Datacaster.instance?(right)
|
|
198
|
+
raise RuntimeError, "provide String, Symbol, Integer or array thereof instead of #{right.inspect}", caller
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
op_caster = op
|
|
202
|
+
if op.is_a?(String) || op.is_a?(Symbol)
|
|
203
|
+
op_caster = check { |(l, r)| l.respond_to?(op) && l.public_send(op, r) }
|
|
204
|
+
elsif !Datacaster.instance?(left)
|
|
205
|
+
raise RuntimeError, "provide String or Symbol instead of #{op.inspect}", caller
|
|
206
|
+
end
|
|
207
|
+
|
|
113
208
|
{left: left, op: op, right: right}.each do |k, v|
|
|
114
209
|
if [String, Symbol, Integer].any? { |c| v.is_a?(c) }
|
|
115
210
|
additional_vars[k] = v
|
|
116
|
-
elsif !Datacaster.instance?(v)
|
|
117
|
-
raise RuntimeError, "expected #{k} to be String, Symbol, Integer or Datacaster::Base, but got #{v.inspect}", caller
|
|
118
211
|
end
|
|
119
212
|
end
|
|
120
213
|
|
|
121
|
-
if
|
|
122
|
-
raise RuntimeError, "expected op to be String, Symbol or Datacaster::Base, but got #{op.inspect}", caller
|
|
123
|
-
end
|
|
124
|
-
|
|
125
|
-
if [left, op, right].none? { |x| Datacaster.instance?(x) }
|
|
214
|
+
if additional_vars.length == 3
|
|
126
215
|
error_keys.unshift(".#{left}.#{op}.#{right}")
|
|
127
216
|
end
|
|
128
217
|
error_keys.unshift(error_key) if error_key
|
|
129
218
|
|
|
130
|
-
left = pick(left) unless Datacaster.instance?(left)
|
|
131
|
-
right = pick(right) unless Datacaster.instance?(right)
|
|
132
|
-
op_caster = op
|
|
133
|
-
unless Datacaster.instance?(op_caster)
|
|
134
|
-
op_caster = check { |(l, r)| l.respond_to?(op) && l.public_send(op, r) }
|
|
135
|
-
end
|
|
136
|
-
|
|
137
219
|
cast do |value|
|
|
138
|
-
left_result =
|
|
220
|
+
left_result = left_caster.(value)
|
|
139
221
|
next left_result unless left_result.valid?
|
|
140
222
|
i18n_var!(:left, left_result.value) unless additional_vars.key?(:left)
|
|
141
223
|
|
|
142
|
-
right_result =
|
|
224
|
+
right_result = right_caster.(value)
|
|
143
225
|
next right_result unless right_result.valid?
|
|
144
226
|
i18n_var!(:right, right_result.value) unless additional_vars.key?(:right)
|
|
145
227
|
|
|
@@ -154,71 +236,21 @@ module Datacaster
|
|
|
154
236
|
transform { Datacaster.absent }
|
|
155
237
|
end
|
|
156
238
|
|
|
157
|
-
def pass
|
|
158
|
-
transform(&:itself)
|
|
159
|
-
end
|
|
160
|
-
|
|
161
|
-
def switch(*base, **on_clauses)
|
|
162
|
-
switch =
|
|
163
|
-
if base.length == 0
|
|
164
|
-
SwitchNode.new
|
|
165
|
-
else
|
|
166
|
-
SwitchNode.new(base)
|
|
167
|
-
end
|
|
168
|
-
on_clauses.reduce(switch) do |result, (k, v)|
|
|
169
|
-
result.on(k, v)
|
|
170
|
-
end
|
|
171
|
-
end
|
|
172
|
-
|
|
173
|
-
def pass_if(base)
|
|
174
|
-
ContextNodes::PassIf.new(base)
|
|
175
|
-
end
|
|
176
|
-
|
|
177
|
-
def pick(*keys, strict: false)
|
|
178
|
-
raise RuntimeError.new("provide keys to pick, e.g. pick(:key)") if keys.empty?
|
|
179
|
-
|
|
180
|
-
must_be(Enumerable) & transform { |value|
|
|
181
|
-
result =
|
|
182
|
-
keys.map do |key|
|
|
183
|
-
if value.respond_to?(:key?) && !value.key?(key)
|
|
184
|
-
Datacaster.absent
|
|
185
|
-
elsif value.respond_to?(:length) && key.is_a?(Integer) && key > 0 && key >= value.length
|
|
186
|
-
Datacaster.absent
|
|
187
|
-
else
|
|
188
|
-
value[key]
|
|
189
|
-
end
|
|
190
|
-
end
|
|
191
|
-
|
|
192
|
-
keys.length == 1 ? result.first : result
|
|
193
|
-
}
|
|
194
|
-
end
|
|
195
|
-
|
|
196
|
-
def merge_message_keys(*keys)
|
|
197
|
-
MessageKeysMerger.new(keys)
|
|
198
|
-
end
|
|
199
|
-
|
|
200
239
|
def responds_to(method, error_key = nil)
|
|
201
240
|
error_keys = ['.responds_to', 'datacaster.errors.responds_to']
|
|
202
241
|
error_keys.unshift(error_key) if error_key
|
|
203
242
|
check { |x| x.respond_to?(method) }.i18n_key(*error_keys, reference: method.to_s)
|
|
204
243
|
end
|
|
205
244
|
|
|
206
|
-
def
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
245
|
+
def switch(base = nil, **on_clauses)
|
|
246
|
+
switch = SwitchNode.new(base)
|
|
247
|
+
on_clauses.reduce(switch) do |result, (k, v)|
|
|
248
|
+
result.on(k, v)
|
|
249
|
+
end
|
|
210
250
|
end
|
|
211
251
|
|
|
212
|
-
def
|
|
213
|
-
|
|
214
|
-
cast do |x|
|
|
215
|
-
if x == Datacaster.absent ||
|
|
216
|
-
(!on.nil? && x.respond_to?(on) && x.public_send(on))
|
|
217
|
-
Datacaster.ValidResult(Datacaster.absent)
|
|
218
|
-
else
|
|
219
|
-
base.(x)
|
|
220
|
-
end
|
|
221
|
-
end
|
|
252
|
+
def transform_to_value(value)
|
|
253
|
+
transform { value }
|
|
222
254
|
end
|
|
223
255
|
|
|
224
256
|
# Strict types
|
|
@@ -1,16 +1,14 @@
|
|
|
1
1
|
module Datacaster
|
|
2
2
|
class SwitchNode < Base
|
|
3
3
|
def initialize(base = nil, on_casters = [], else_caster = nil)
|
|
4
|
-
base = base
|
|
4
|
+
@base = base
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
@base = Datacaster::Predefined.pick(base)
|
|
13
|
-
else
|
|
6
|
+
if Datacaster::Utils.pickable?(@base)
|
|
7
|
+
@base = Datacaster::Predefined.pick(@base)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
if !@base.nil? && !Datacaster.instance?(@base)
|
|
11
|
+
puts @base.inspect
|
|
14
12
|
raise RuntimeError, "provide a Datacaster::Base instance, a hash key, or an array of keys to switch(...) caster", caller
|
|
15
13
|
end
|
|
16
14
|
|
|
@@ -18,11 +16,18 @@ module Datacaster
|
|
|
18
16
|
@else = else_caster
|
|
19
17
|
end
|
|
20
18
|
|
|
21
|
-
def on(caster_or_value, clause)
|
|
19
|
+
def on(caster_or_value, clause, strict: false)
|
|
22
20
|
caster =
|
|
23
21
|
case caster_or_value
|
|
24
22
|
when Datacaster::Base
|
|
25
23
|
caster_or_value
|
|
24
|
+
when String, Symbol
|
|
25
|
+
if strict
|
|
26
|
+
Datacaster::Predefined.compare(caster_or_value)
|
|
27
|
+
else
|
|
28
|
+
Datacaster::Predefined.compare(caster_or_value.to_s) |
|
|
29
|
+
Datacaster::Predefined.compare(caster_or_value.to_sym)
|
|
30
|
+
end
|
|
26
31
|
else
|
|
27
32
|
Datacaster::Predefined.compare(caster_or_value)
|
|
28
33
|
end
|
data/lib/datacaster/utils.rb
CHANGED
|
@@ -30,5 +30,11 @@ module Datacaster
|
|
|
30
30
|
|
|
31
31
|
result
|
|
32
32
|
end
|
|
33
|
+
|
|
34
|
+
def pickable?(value)
|
|
35
|
+
is_literal = ->(v) { [String, Symbol, Integer].any? { |c| v.is_a?(c) } }
|
|
36
|
+
is_literal.(value) ||
|
|
37
|
+
value.is_a?(Array) && !value.empty? && value.all? { |v| is_literal.(v) }
|
|
38
|
+
end
|
|
33
39
|
end
|
|
34
40
|
end
|
data/lib/datacaster/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: datacaster
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 3.1.
|
|
4
|
+
version: 3.1.5
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Eugene Zolotarev
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2023-10-
|
|
11
|
+
date: 2023-10-07 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activemodel
|