datacaster 5.0.1 → 6.0.2
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 +34 -24
- data/lib/datacaster/array_schema.rb +1 -1
- data/lib/datacaster/predefined.rb +5 -1
- data/lib/datacaster/version.rb +1 -1
- metadata +7 -7
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f66df22c1ea20054ae2b16ea8ccbd778b8aac71e7898bc763036e3c4f9ba50da
|
|
4
|
+
data.tar.gz: bad95a5182fdbbefe72c5c8f5b724c433f26cc5d676a755dcb0af554e07d95ca
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f6f707de2a1555d6dbc7756b60e8a981de97f137787dc5212b78807060d43877e0c5b18f3ad191262eabb618bed356feb32e9d96d3adf93b14bbbbe73bf2452b
|
|
7
|
+
data.tar.gz: 8612f9609a9d1c9a8a9de4358ee66c30458158598917a3e59d09fb83582a8cdc68f7c395f577179363407fd63cbd9f72d4864b77ee957f4e4e63f6a2aad746f2
|
data/README.md
CHANGED
|
@@ -34,6 +34,7 @@ It is currently used in production in several projects (mainly as request parame
|
|
|
34
34
|
- [`maximum(max, error_key = nil, inclusive: true)`](#maximummax-error_key--nil-inclusive-true)
|
|
35
35
|
- [`minimum(min, error_key = nil, inclusive: true)`](#minimummin-error_key--nil-inclusive-true)
|
|
36
36
|
- [`non_empty_string(error_key = nil)`](#non_empty_stringerror_key--nil)
|
|
37
|
+
- [`non_empty_array(error_keys = {}`](#non_empty_arrayerror_keys--)
|
|
37
38
|
- [`pattern(regexp, error_key = nil)`](#patternregexp-error_key--nil)
|
|
38
39
|
- [`uuid(error_key = nil)`](#uuiderror_key--nil)
|
|
39
40
|
- [Special types](#special-types)
|
|
@@ -159,7 +160,7 @@ validator.("test") # Datacaster::ErrorResult(["is invalid"])
|
|
|
159
160
|
|
|
160
161
|
In the code above we ensure that validated value is:
|
|
161
162
|
|
|
162
|
-
a) a string
|
|
163
|
+
a) a string,\
|
|
163
164
|
b) has length > 5.
|
|
164
165
|
|
|
165
166
|
If first condition is not met, second one is not evaluated at all (i.e. evaluation is always "short-circuit", just as one might expect).
|
|
@@ -203,9 +204,9 @@ Validating hashes is the main case scenario for datacaster. Several specific con
|
|
|
203
204
|
|
|
204
205
|
Let's assume we want to validate that a hash (which represents data about a person):
|
|
205
206
|
|
|
206
|
-
a) is, in fact, a Hash
|
|
207
|
-
b) has exactly 2 keys, `name` and `salary
|
|
208
|
-
c) key 'name' is a string
|
|
207
|
+
a) is, in fact, a Hash;\
|
|
208
|
+
b) has exactly 2 keys, `name` and `salary`,\
|
|
209
|
+
c) key 'name' is a string,\
|
|
209
210
|
d) key 'salary' is an integer:
|
|
210
211
|
|
|
211
212
|
```ruby
|
|
@@ -332,7 +333,7 @@ Notice that OR operator, if left-hand validation fails, passes the original valu
|
|
|
332
333
|
|
|
333
334
|
#### *IF... THEN... ELSE operator*
|
|
334
335
|
|
|
335
|
-
Let's
|
|
336
|
+
Let's suppose we want to run different validations depending on some value, e.g.:
|
|
336
337
|
|
|
337
338
|
* if 'salary' is more than 100_000, check for the additional key, 'passport'
|
|
338
339
|
* otherwise, ensure 'passport' key is absent
|
|
@@ -373,7 +374,7 @@ Formally, with `a.then(b).else(c)`:
|
|
|
373
374
|
|
|
374
375
|
Note: this construct is *not* an equivalent of `a & b | c`.
|
|
375
376
|
|
|
376
|
-
With `a.then(b).else(c)` if `a` and `b` fails, then `b`'s error is returned. With `a & b | c`, instead, `c`'s result would be returned.
|
|
377
|
+
With `a.then(b).else(c)` if `a` passes and `b` fails, then `b`'s error is returned. With `a & b | c`, instead, `c`'s result would be returned.
|
|
377
378
|
|
|
378
379
|
#### *SWITCH... ON... ELSE operator*
|
|
379
380
|
|
|
@@ -561,6 +562,15 @@ I18n keys:
|
|
|
561
562
|
* not a string – `error_key`, `'.string'`, `'datacaster.errors.string'`
|
|
562
563
|
* is empty – `error_key`, `'.non_empty_string'`, `'datacaster.errors.non_empty_string'`
|
|
563
564
|
|
|
565
|
+
#### `non_empty_array(error_keys = {})`
|
|
566
|
+
|
|
567
|
+
Returns ValidResult if and only if provided value is an array and is not empty. Doesn't transform the value.
|
|
568
|
+
|
|
569
|
+
I18n keys:
|
|
570
|
+
|
|
571
|
+
* not an array – `error_keys[:array]`, `'.array'`, `'datacaster.errors.array'`
|
|
572
|
+
* empty array – `error_keys[:empty]`, `'.empty'`, `'datacaster.errors.empty'`
|
|
573
|
+
|
|
564
574
|
#### `pattern(regexp, error_key = nil)`
|
|
565
575
|
|
|
566
576
|
Returns ValidResult if and only if provided value is a string and satisfies regexp. Doesn't transform the value. Don't forget to provide start/end markers in the regexp if needed, e.g. `/\A\d+\z/` for digits-only string.
|
|
@@ -742,7 +752,7 @@ I18n keys:
|
|
|
742
752
|
|
|
743
753
|
Returns ValidResult if and only if the value `#is_a?(klass)`. Doesn't transform the value.
|
|
744
754
|
|
|
745
|
-
I18n keys: `error_key`, `'.must_be'`, `'datacaster.errors.must_be'`. Adds `reference` i18n variable, setting it to `klass.name`.
|
|
755
|
+
I18n keys: `error_key`, `'.must_be'`, `'datacaster.errors.must_be'`. Adds `reference` i18n variable, setting it to `klass.name`.
|
|
746
756
|
|
|
747
757
|
#### `optional(base, on: nil)`
|
|
748
758
|
|
|
@@ -1128,13 +1138,13 @@ To define compound data type, array of 'something', use `array_schema(something)
|
|
|
1128
1138
|
salaries = Datacaster.schema { array_of(integer) }
|
|
1129
1139
|
|
|
1130
1140
|
salaries.([1000, 2000, 3000]) # Datacaster::ValidResult([1000, 2000, 3000])
|
|
1141
|
+
salaries.([]) # Datacaster::ValidResult([])
|
|
1131
1142
|
|
|
1132
1143
|
salaries.(["one thousand"]) # Datacaster::ErrorResult({0=>["is not an integer"]})
|
|
1133
1144
|
salaries.(:not_an_array) # Datacaster::ErrorResult(["should be an array"])
|
|
1134
|
-
salaries.([]) # Datacaster::ErrorResult(["should not be empty"])
|
|
1135
1145
|
```
|
|
1136
1146
|
|
|
1137
|
-
To
|
|
1147
|
+
To disallow empty array use the following construct: `array_of(..., allow_empty: false)`.
|
|
1138
1148
|
|
|
1139
1149
|
If you want to define an array of hashes, [shortcut definition](#shortcut-nested-definitions) could be used: instead of `array_of(hash_schema({...}))` use `array_of({...})`:
|
|
1140
1150
|
|
|
@@ -1162,12 +1172,12 @@ Notice that extra keys of inner hashes could be validated only if each element i
|
|
|
1162
1172
|
|
|
1163
1173
|
Formally, `array_of(x, error_keys = {})` will return ValidResult if and only if:
|
|
1164
1174
|
|
|
1165
|
-
a) provided value implements basic array methods (`#map`, `#zip`)
|
|
1166
|
-
b) provided value is not `#empty
|
|
1175
|
+
a) provided value implements basic array methods (`#map`, `#zip`),\
|
|
1176
|
+
b) provided value is not `#empty?`,\
|
|
1167
1177
|
c) each element of the provided value passes validation of `x`.
|
|
1168
1178
|
|
|
1169
|
-
If a) fails, `ErrorResult(["should be an array"]) is returned
|
|
1170
|
-
If b) fails, `ErrorResult(["should not be empty"])` is returned
|
|
1179
|
+
If a) fails, `ErrorResult(["should be an array"])` is returned.\
|
|
1180
|
+
If b) fails, `ErrorResult(["should not be empty"])` is returned.\
|
|
1171
1181
|
If c) fails, `ErrorResult({0 => ..., 1 => ...})` is returned. Wrapped hash contains keys which correspond to initial array's indices, and values correspond to failure returned from `x` validator, called for the corresponding element.
|
|
1172
1182
|
|
|
1173
1183
|
Array schema transforms array if inner type (`x`) transforms element (in this case `array_schema` works more or less like `map` function). Otherwise, it doesn't transform.
|
|
@@ -1201,12 +1211,12 @@ person.(name: "John Smith", salary: "100_000")
|
|
|
1201
1211
|
|
|
1202
1212
|
Formally, hash schema returns ValidResult if and only if:
|
|
1203
1213
|
|
|
1204
|
-
a) provided value `is_a?(Hash)
|
|
1205
|
-
b) all values, fetched by keys mentioned in `hash_schema(...)` definition, pass corresponding validations
|
|
1214
|
+
a) provided value `is_a?(Hash)`,\
|
|
1215
|
+
b) all values, fetched by keys mentioned in `hash_schema(...)` definition, pass corresponding validations,\
|
|
1206
1216
|
c) after all checks (including logical operators), there are no unchecked keys in the hash.
|
|
1207
1217
|
|
|
1208
|
-
If a) fails, `ErrorResult(["is not a hash"])` is returned
|
|
1209
|
-
if b) fails, `ErrorResult(key1 => [errors...], key2 => [errors...])` is returned. Each key of wrapped "error hash" corresponds to the key of validated hash, and each value of "error hash" contains array of errors, returned by the corresponding validator
|
|
1218
|
+
If a) fails, `ErrorResult(["is not a hash"])` is returned.\
|
|
1219
|
+
if b) fails, `ErrorResult(key1 => [errors...], key2 => [errors...])` is returned. Each key of wrapped "error hash" corresponds to the key of validated hash, and each value of "error hash" contains array of errors, returned by the corresponding validator.\
|
|
1210
1220
|
If b) is fulfilled, then and only then validated hash is checked for extra keys. If they are found, `ErrorResult(extra_key_1 => ["should be absent"], ...)` is returned.
|
|
1211
1221
|
|
|
1212
1222
|
I18n keys:
|
|
@@ -1371,11 +1381,11 @@ Had we used `schema` everywhere, `CommonFieldsValidator` would return failure fo
|
|
|
1371
1381
|
|
|
1372
1382
|
As a rule of thumb, use `partial_schema` in any "intermediary" validators (extracted for the sake of clarity of code and reusability) and use `schema` in any "end" validators (ones which receive full record as input and use intermediary validators behind the scenes).
|
|
1373
1383
|
|
|
1374
|
-
Lastly, if you want to just delete extra unvalidated keys without returning
|
|
1384
|
+
Lastly, if you want to just delete extra unvalidated keys without returning an error, use `choosy_schema`.
|
|
1375
1385
|
|
|
1376
1386
|
#### AND with error aggregation (`*`)
|
|
1377
1387
|
|
|
1378
|
-
Often it is useful to run
|
|
1388
|
+
Often it is useful to run validators which are "further down the conveyor" (i.e. placed at the right-hand side of AND operator `&`) even if current (i.e. left-hand side) validator has failed.
|
|
1379
1389
|
|
|
1380
1390
|
Let's say we have extracted some "common validations" and have some concrete validators, which utilize these reusable common validations (more or less repeating the motif of the previous example, shortening non-essential for this section parts for clarity):
|
|
1381
1391
|
|
|
@@ -1500,10 +1510,10 @@ Of course, order of keys in the definition hash doesn't change the result.
|
|
|
1500
1510
|
|
|
1501
1511
|
Formally, `transform_to_hash`:
|
|
1502
1512
|
|
|
1503
|
-
a) transforms (any) value to hash
|
|
1504
|
-
b) this hash will contain keys listed in `transform_to_hash` definition
|
|
1505
|
-
c) value of these keys will be: initial value (*not the corresponding key of it, the value altogether*) transformed with the corresponding validator/type
|
|
1506
|
-
d) if any of the values from c) happen to be `Datacaster.absent`, this value *with its key* is removed from the resultant hash
|
|
1513
|
+
a) transforms (any) value to hash;\
|
|
1514
|
+
b) this hash will contain keys listed in `transform_to_hash` definition;\
|
|
1515
|
+
c) value of these keys will be: initial value (*not the corresponding key of it, the value altogether*) transformed with the corresponding validator/type;\
|
|
1516
|
+
d) if any of the values from c) happen to be `Datacaster.absent`, this value *with its key* is removed from the resultant hash;\
|
|
1507
1517
|
e) if the initial value happens to also be a hash, all its unvalidated (unused) keys are merged to the resultant hash.
|
|
1508
1518
|
|
|
1509
1519
|
`transform_to_hash` will return ValidResult if and only if all transformations return ValidResults.
|
|
@@ -1793,7 +1803,7 @@ All keyword arguments of `#i18n_key`, `#i18n_scope` and designed for that sole p
|
|
|
1793
1803
|
|
|
1794
1804
|
It is possible to add i18n variables at the runtime (e.g. inside `check { ... }` block) by calling `i18n_vars!(variable: 'value')` or `i18n_var!(:variable, 'value')`.
|
|
1795
1805
|
|
|
1796
|
-
Outer calls of `#i18n_key` (`#i18n_scope`, `#i18n_vars`) have
|
|
1806
|
+
Outer calls of `#i18n_key` (`#i18n_scope`, `#i18n_vars`) have precedence before the inner if variable names collide. However, runtime calls of `#i18n_vars!` and `#i18n_var!` overwrite compile-time variables from the next nearest key, scope or vars on collision.
|
|
1797
1807
|
|
|
1798
1808
|
## Registering custom 'predefined' types
|
|
1799
1809
|
|
|
@@ -40,7 +40,7 @@ module Datacaster
|
|
|
40
40
|
Trier.new(catched_exception, error_key, &block)
|
|
41
41
|
end
|
|
42
42
|
|
|
43
|
-
def array_schema(element_caster, error_keys = {}, allow_empty:
|
|
43
|
+
def array_schema(element_caster, error_keys = {}, allow_empty: true)
|
|
44
44
|
ArraySchema.new(DefinitionDSL.expand(element_caster), error_keys, allow_empty:)
|
|
45
45
|
end
|
|
46
46
|
alias_method :array_of, :array_schema
|
|
@@ -451,6 +451,10 @@ module Datacaster
|
|
|
451
451
|
string(error_key) & check { |x| !x.empty? }.i18n_key(*error_keys)
|
|
452
452
|
end
|
|
453
453
|
|
|
454
|
+
def non_empty_array(error_keys = {})
|
|
455
|
+
array_of(any, error_keys, allow_empty: false)
|
|
456
|
+
end
|
|
457
|
+
|
|
454
458
|
def uuid(error_key = nil)
|
|
455
459
|
error_keys = ['.uuid', 'datacaster.errors.uuid']
|
|
456
460
|
error_keys.unshift(error_key) if error_key
|
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:
|
|
4
|
+
version: 6.0.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Eugene Zolotarev
|
|
8
|
-
autorequire:
|
|
8
|
+
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2025-
|
|
11
|
+
date: 2025-10-21 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activemodel
|
|
@@ -106,7 +106,7 @@ dependencies:
|
|
|
106
106
|
- - "<"
|
|
107
107
|
- !ruby/object:Gem::Version
|
|
108
108
|
version: '3'
|
|
109
|
-
description:
|
|
109
|
+
description:
|
|
110
110
|
email:
|
|
111
111
|
- eugzol@gmail.com
|
|
112
112
|
executables: []
|
|
@@ -181,7 +181,7 @@ licenses:
|
|
|
181
181
|
- MIT
|
|
182
182
|
metadata:
|
|
183
183
|
source_code_uri: https://github.com/EugZol/datacaster
|
|
184
|
-
post_install_message:
|
|
184
|
+
post_install_message:
|
|
185
185
|
rdoc_options: []
|
|
186
186
|
require_paths:
|
|
187
187
|
- lib
|
|
@@ -196,8 +196,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
196
196
|
- !ruby/object:Gem::Version
|
|
197
197
|
version: '0'
|
|
198
198
|
requirements: []
|
|
199
|
-
rubygems_version: 3.
|
|
200
|
-
signing_key:
|
|
199
|
+
rubygems_version: 3.1.6
|
|
200
|
+
signing_key:
|
|
201
201
|
specification_version: 4
|
|
202
202
|
summary: Run-time type checker and transformer for Ruby
|
|
203
203
|
test_files: []
|