rschema 3.0.1.pre3 → 3.0.1.pre4
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 +278 -330
- data/lib/rschema.rb +104 -17
- data/lib/rschema/coercers.rb +3 -0
- data/lib/rschema/coercers/any.rb +40 -0
- data/lib/rschema/coercers/boolean.rb +30 -0
- data/lib/rschema/coercers/chain.rb +41 -0
- data/lib/rschema/coercers/date.rb +25 -0
- data/lib/rschema/coercers/fixed_hash/default_booleans_to_false.rb +62 -0
- data/lib/rschema/coercers/fixed_hash/remove_extraneous_attributes.rb +42 -0
- data/lib/rschema/coercers/fixed_hash/symbolize_keys.rb +62 -0
- data/lib/rschema/coercers/float.rb +18 -0
- data/lib/rschema/coercers/integer.rb +18 -0
- data/lib/rschema/coercers/symbol.rb +21 -0
- data/lib/rschema/coercers/time.rb +25 -0
- data/lib/rschema/coercion_wrapper.rb +46 -0
- data/lib/rschema/coercion_wrapper/rack_params.rb +21 -0
- data/lib/rschema/dsl.rb +271 -42
- data/lib/rschema/error.rb +12 -30
- data/lib/rschema/options.rb +2 -2
- data/lib/rschema/result.rb +18 -4
- data/lib/rschema/schemas.rb +3 -0
- data/lib/rschema/schemas/anything.rb +14 -12
- data/lib/rschema/schemas/boolean.rb +20 -21
- data/lib/rschema/schemas/coercer.rb +37 -0
- data/lib/rschema/schemas/convenience.rb +53 -0
- data/lib/rschema/schemas/enum.rb +25 -25
- data/lib/rschema/schemas/fixed_hash.rb +110 -91
- data/lib/rschema/schemas/fixed_length_array.rb +48 -48
- data/lib/rschema/schemas/maybe.rb +18 -17
- data/lib/rschema/schemas/pipeline.rb +20 -19
- data/lib/rschema/schemas/predicate.rb +24 -21
- data/lib/rschema/schemas/set.rb +40 -45
- data/lib/rschema/schemas/sum.rb +24 -28
- data/lib/rschema/schemas/type.rb +22 -21
- data/lib/rschema/schemas/variable_hash.rb +53 -52
- data/lib/rschema/schemas/variable_length_array.rb +39 -38
- data/lib/rschema/version.rb +1 -1
- metadata +49 -5
- data/lib/rschema/http_coercer.rb +0 -218
@@ -1,60 +1,60 @@
|
|
1
1
|
module RSchema
|
2
|
-
|
3
|
-
|
4
|
-
|
2
|
+
module Schemas
|
3
|
+
class FixedLengthArray
|
4
|
+
attr_reader :subschemas
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
6
|
+
def initialize(subschemas)
|
7
|
+
@subschemas = subschemas
|
8
|
+
end
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
unless value.size == @subschemas.size
|
20
|
-
return Result.failure(Error.new(
|
21
|
-
symbolic_name: :incorrect_size,
|
22
|
-
schema: self,
|
23
|
-
value: value,
|
24
|
-
))
|
25
|
-
end
|
26
|
-
|
27
|
-
validate_value, error = apply_subschemas(value, options)
|
28
|
-
if error.empty?
|
29
|
-
Result.success(validate_value)
|
30
|
-
else
|
31
|
-
Result.failure(error)
|
32
|
-
end
|
33
|
-
end
|
10
|
+
def call(value, options)
|
11
|
+
unless value.kind_of?(Array)
|
12
|
+
return Result.failure(Error.new(
|
13
|
+
symbolic_name: :not_an_array,
|
14
|
+
schema: self,
|
15
|
+
value: value,
|
16
|
+
))
|
17
|
+
end
|
34
18
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
19
|
+
unless value.size == @subschemas.size
|
20
|
+
return Result.failure(Error.new(
|
21
|
+
symbolic_name: :incorrect_size,
|
22
|
+
schema: self,
|
23
|
+
value: value,
|
24
|
+
))
|
25
|
+
end
|
39
26
|
|
40
|
-
|
27
|
+
validate_value, error = apply_subschemas(value, options)
|
28
|
+
if error.empty?
|
29
|
+
Result.success(validate_value)
|
30
|
+
else
|
31
|
+
Result.failure(error)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def with_wrapped_subschemas(wrapper)
|
36
|
+
wrapped_subschemas = subschemas.map{ |ss| wrapper.wrap(ss) }
|
37
|
+
self.class.new(wrapped_subschemas)
|
38
|
+
end
|
41
39
|
|
42
|
-
|
43
|
-
validate_value = []
|
44
|
-
errors = {}
|
40
|
+
private
|
45
41
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
validate_value << result.value
|
50
|
-
else
|
51
|
-
errors[idx] = result.error
|
52
|
-
break if options.fail_fast?
|
53
|
-
end
|
54
|
-
end
|
42
|
+
def apply_subschemas(array_value, options)
|
43
|
+
validate_value = []
|
44
|
+
errors = {}
|
55
45
|
|
56
|
-
|
46
|
+
array_value.zip(@subschemas).each_with_index do |(subvalue, subschema), idx|
|
47
|
+
result = subschema.call(subvalue, options)
|
48
|
+
if result.valid?
|
49
|
+
validate_value << result.value
|
50
|
+
else
|
51
|
+
errors[idx] = result.error
|
52
|
+
break if options.fail_fast?
|
57
53
|
end
|
58
54
|
end
|
55
|
+
|
56
|
+
[validate_value, errors]
|
59
57
|
end
|
60
58
|
end
|
59
|
+
end
|
60
|
+
end
|
@@ -1,23 +1,24 @@
|
|
1
1
|
module RSchema
|
2
|
-
|
3
|
-
|
4
|
-
|
2
|
+
module Schemas
|
3
|
+
class Maybe
|
4
|
+
attr_reader :subschema
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
def call(value, options=Options.default)
|
11
|
-
if value == nil
|
12
|
-
Result.success(value)
|
13
|
-
else
|
14
|
-
@subschema.call(value, options)
|
15
|
-
end
|
16
|
-
end
|
6
|
+
def initialize(subschema)
|
7
|
+
@subschema = subschema
|
8
|
+
end
|
17
9
|
|
18
|
-
|
19
|
-
|
20
|
-
|
10
|
+
def call(value, options)
|
11
|
+
if value == nil
|
12
|
+
Result.success(value)
|
13
|
+
else
|
14
|
+
@subschema.call(value, options)
|
21
15
|
end
|
22
16
|
end
|
17
|
+
|
18
|
+
def with_wrapped_subschemas(wrapper)
|
19
|
+
self.class.new(wrapper.wrap(subschema))
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
23
24
|
end
|
@@ -1,27 +1,28 @@
|
|
1
1
|
module RSchema
|
2
|
-
|
3
|
-
|
4
|
-
|
2
|
+
module Schemas
|
3
|
+
class Pipeline
|
4
|
+
attr_reader :subschemas
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
6
|
+
def initialize(subschemas)
|
7
|
+
@subschemas = subschemas
|
8
|
+
end
|
9
9
|
|
10
|
-
|
11
|
-
|
10
|
+
def call(value, options)
|
11
|
+
result = Result.success(value)
|
12
12
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
13
|
+
subschemas.each do |subsch|
|
14
|
+
result = subsch.call(result.value, options)
|
15
|
+
break if result.invalid?
|
16
|
+
end
|
17
17
|
|
18
|
-
|
19
|
-
|
18
|
+
result
|
19
|
+
end
|
20
20
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
end
|
25
|
-
end
|
21
|
+
def with_wrapped_subschemas(wrapper)
|
22
|
+
wrapped_subschemas = subschemas.map{ |ss| wrapper.wrap(ss) }
|
23
|
+
self.class.new(wrapped_subschemas)
|
26
24
|
end
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
27
28
|
end
|
@@ -1,27 +1,30 @@
|
|
1
1
|
module RSchema
|
2
|
-
|
3
|
-
|
4
|
-
|
2
|
+
module Schemas
|
3
|
+
class Predicate
|
4
|
+
attr_reader :block, :name
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
def call(value, options=Options.default)
|
11
|
-
if block.call(value)
|
12
|
-
Result.success(value)
|
13
|
-
else
|
14
|
-
Result.failure(Error.new(
|
15
|
-
schema: self,
|
16
|
-
value: value,
|
17
|
-
symbolic_name: :false,
|
18
|
-
))
|
19
|
-
end
|
20
|
-
end
|
6
|
+
def initialize(name = nil, &block)
|
7
|
+
@block = block
|
8
|
+
@name = name
|
9
|
+
end
|
21
10
|
|
22
|
-
|
23
|
-
|
24
|
-
|
11
|
+
def call(value, options)
|
12
|
+
if block.call(value)
|
13
|
+
Result.success(value)
|
14
|
+
else
|
15
|
+
Result.failure(Error.new(
|
16
|
+
schema: self,
|
17
|
+
value: value,
|
18
|
+
symbolic_name: :false,
|
19
|
+
vars: { predicate_name: name }
|
20
|
+
))
|
25
21
|
end
|
26
22
|
end
|
23
|
+
|
24
|
+
def with_wrapped_subschemas(wrapper)
|
25
|
+
self
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
27
30
|
end
|
data/lib/rschema/schemas/set.rb
CHANGED
@@ -1,56 +1,51 @@
|
|
1
1
|
require 'set'
|
2
2
|
|
3
3
|
module RSchema
|
4
|
-
|
5
|
-
|
6
|
-
|
4
|
+
module Schemas
|
5
|
+
class Set
|
6
|
+
attr_reader :subschema
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
8
|
+
def initialize(subschema)
|
9
|
+
@subschema = subschema
|
10
|
+
end
|
11
11
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
result_value = ::Set.new
|
16
|
-
result_errors = []
|
17
|
-
|
18
|
-
value.each do |subvalue|
|
19
|
-
subresult = subschema.call(subvalue, options)
|
20
|
-
if subresult.valid?
|
21
|
-
result_value << subresult.value
|
22
|
-
else
|
23
|
-
result_errors << subresult.error
|
24
|
-
end
|
25
|
-
|
26
|
-
break if options.fail_fast?
|
27
|
-
end
|
28
|
-
|
29
|
-
if result_errors.empty?
|
30
|
-
Result.success(result_value)
|
31
|
-
else
|
32
|
-
Result.failure(Error.new(
|
33
|
-
schema: self,
|
34
|
-
value: value,
|
35
|
-
symbolic_name: :contents_invalid,
|
36
|
-
vars: result_errors,
|
37
|
-
))
|
38
|
-
end
|
39
|
-
end
|
12
|
+
def call(value, options)
|
13
|
+
return not_a_set_result(value) unless value.is_a?(::Set)
|
40
14
|
|
41
|
-
|
42
|
-
|
43
|
-
|
15
|
+
result_value = ::Set.new
|
16
|
+
result_errors = {}
|
17
|
+
|
18
|
+
value.each do |subvalue|
|
19
|
+
subresult = subschema.call(subvalue, options)
|
20
|
+
if subresult.valid?
|
21
|
+
result_value << subresult.value
|
22
|
+
else
|
23
|
+
result_errors[subvalue] = subresult.error
|
44
24
|
end
|
45
25
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
end
|
26
|
+
break if options.fail_fast?
|
27
|
+
end
|
28
|
+
|
29
|
+
if result_errors.empty?
|
30
|
+
Result.success(result_value)
|
31
|
+
else
|
32
|
+
Result.failure(result_errors)
|
54
33
|
end
|
55
34
|
end
|
35
|
+
|
36
|
+
def with_wrapped_subschemas(wrapper)
|
37
|
+
wrapped_subschema = wrapper.wrap(subschema)
|
38
|
+
self.class.new(wrapped_subschema)
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
def not_a_set_result(value)
|
43
|
+
Result.failure(Error.new(
|
44
|
+
schema: self,
|
45
|
+
symbolic_name: :not_a_set,
|
46
|
+
value: value,
|
47
|
+
))
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
56
51
|
end
|
data/lib/rschema/schemas/sum.rb
CHANGED
@@ -1,36 +1,32 @@
|
|
1
1
|
module RSchema
|
2
|
-
|
3
|
-
|
4
|
-
|
2
|
+
module Schemas
|
3
|
+
class Sum
|
4
|
+
attr_reader :subschemas
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
def call(value, options=Options.default)
|
11
|
-
suberrors = []
|
12
|
-
|
13
|
-
@subschemas.each do |subsch|
|
14
|
-
result = subsch.call(value, options)
|
15
|
-
if result.valid?
|
16
|
-
return result
|
17
|
-
else
|
18
|
-
suberrors << result.error
|
19
|
-
end
|
20
|
-
end
|
6
|
+
def initialize(subschemas)
|
7
|
+
@subschemas = subschemas
|
8
|
+
end
|
21
9
|
|
22
|
-
|
23
|
-
|
24
|
-
value: value,
|
25
|
-
symbolic_name: :all_invalid,
|
26
|
-
vars: suberrors,
|
27
|
-
))
|
28
|
-
end
|
10
|
+
def call(value, options)
|
11
|
+
suberrors = []
|
29
12
|
|
30
|
-
|
31
|
-
|
32
|
-
|
13
|
+
@subschemas.each do |subsch|
|
14
|
+
result = subsch.call(value, options)
|
15
|
+
if result.valid?
|
16
|
+
return result
|
17
|
+
else
|
18
|
+
suberrors << result.error
|
33
19
|
end
|
34
20
|
end
|
21
|
+
|
22
|
+
Result.failure(suberrors)
|
35
23
|
end
|
24
|
+
|
25
|
+
def with_wrapped_subschemas(wrapper)
|
26
|
+
wrapped_subschemas = subschemas.map{ |ss| wrapper.wrap(ss) }
|
27
|
+
self.class.new(wrapped_subschemas)
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
36
32
|
end
|
data/lib/rschema/schemas/type.rb
CHANGED
@@ -1,27 +1,28 @@
|
|
1
1
|
module RSchema
|
2
|
-
|
3
|
-
|
4
|
-
|
2
|
+
module Schemas
|
3
|
+
class Type
|
4
|
+
attr_reader :type
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
def call(value, options = RSchema::Options.default)
|
11
|
-
if value.is_a?(@type)
|
12
|
-
Result.success(value)
|
13
|
-
else
|
14
|
-
Result.failure(Error.new(
|
15
|
-
schema: self,
|
16
|
-
value: value,
|
17
|
-
symbolic_name: :wrong_type,
|
18
|
-
))
|
19
|
-
end
|
20
|
-
end
|
6
|
+
def initialize(type)
|
7
|
+
@type = type
|
8
|
+
end
|
21
9
|
|
22
|
-
|
23
|
-
|
24
|
-
|
10
|
+
def call(value, options)
|
11
|
+
if value.is_a?(@type)
|
12
|
+
Result.success(value)
|
13
|
+
else
|
14
|
+
Result.failure(Error.new(
|
15
|
+
schema: self,
|
16
|
+
value: value,
|
17
|
+
symbolic_name: :wrong_type,
|
18
|
+
))
|
25
19
|
end
|
26
20
|
end
|
21
|
+
|
22
|
+
def with_wrapped_subschemas(wrapper)
|
23
|
+
self
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
27
28
|
end
|