rschema 3.1.1 → 3.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/lib/rschema.rb +13 -5
  3. data/lib/rschema/coercers.rb +2 -0
  4. data/lib/rschema/coercers/any.rb +37 -31
  5. data/lib/rschema/coercers/boolean.rb +33 -23
  6. data/lib/rschema/coercers/chain.rb +38 -32
  7. data/lib/rschema/coercers/date.rb +29 -20
  8. data/lib/rschema/coercers/fixed_hash/default_arrays_to_empty.rb +57 -56
  9. data/lib/rschema/coercers/fixed_hash/default_booleans_to_false.rb +56 -55
  10. data/lib/rschema/coercers/fixed_hash/remove_extraneous_attributes.rb +43 -39
  11. data/lib/rschema/coercers/fixed_hash/symbolize_keys.rb +55 -51
  12. data/lib/rschema/coercers/float.rb +22 -15
  13. data/lib/rschema/coercers/integer.rb +21 -15
  14. data/lib/rschema/coercers/nil_empty_strings.rb +20 -17
  15. data/lib/rschema/coercers/symbol.rb +20 -17
  16. data/lib/rschema/coercers/time.rb +29 -20
  17. data/lib/rschema/coercion_wrapper.rb +25 -26
  18. data/lib/rschema/coercion_wrapper/rack_params.rb +18 -19
  19. data/lib/rschema/dsl.rb +20 -13
  20. data/lib/rschema/error.rb +9 -4
  21. data/lib/rschema/options.rb +5 -0
  22. data/lib/rschema/rails.rb +60 -0
  23. data/lib/rschema/result.rb +9 -11
  24. data/lib/rschema/schemas.rb +2 -0
  25. data/lib/rschema/schemas/anything.rb +23 -24
  26. data/lib/rschema/schemas/boolean.rb +36 -30
  27. data/lib/rschema/schemas/coercer.rb +47 -46
  28. data/lib/rschema/schemas/convenience.rb +122 -123
  29. data/lib/rschema/schemas/enum.rb +41 -34
  30. data/lib/rschema/schemas/fixed_hash.rb +165 -162
  31. data/lib/rschema/schemas/fixed_length_array.rb +66 -58
  32. data/lib/rschema/schemas/maybe.rb +28 -28
  33. data/lib/rschema/schemas/pipeline.rb +35 -35
  34. data/lib/rschema/schemas/predicate.rb +40 -34
  35. data/lib/rschema/schemas/set.rb +57 -48
  36. data/lib/rschema/schemas/sum.rb +31 -34
  37. data/lib/rschema/schemas/type.rb +44 -38
  38. data/lib/rschema/schemas/variable_hash.rb +63 -61
  39. data/lib/rschema/schemas/variable_length_array.rb +57 -51
  40. data/lib/rschema/version.rb +3 -1
  41. metadata +54 -25
@@ -1,78 +1,80 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module RSchema
2
- module Schemas
4
+ module Schemas
5
+ #
6
+ # A schema that matches variable-sized `Hash` objects, where the keys are
7
+ # _not_ known ahead of time.
8
+ #
9
+ # @example A hash of integers to strings
10
+ # schema = RSchema.define { variable_hash(_Integer => _String) }
11
+ # schema.valid?({ 5 => "hello", 7 => "world" }) #=> true
12
+ # schema.valid?({}) #=> true
13
+ #
14
+ class VariableHash
15
+ attr_reader :key_schema, :value_schema
3
16
 
4
- #
5
- # A schema that matches variable-sized `Hash` objects, where the keys are _not_
6
- # known ahead of time.
7
- #
8
- # @example A hash of integers to strings
9
- # schema = RSchema.define { variable_hash(_Integer => _String) }
10
- # schema.valid?({ 5 => "hello", 7 => "world" }) #=> true
11
- # schema.valid?({}) #=> true
12
- #
13
- class VariableHash
14
- attr_reader :key_schema, :value_schema
17
+ def initialize(key_schema, value_schema)
18
+ @key_schema = key_schema
19
+ @value_schema = value_schema
20
+ end
15
21
 
16
- def initialize(key_schema, value_schema)
17
- @key_schema = key_schema
18
- @value_schema = value_schema
19
- end
22
+ def call(value, options)
23
+ return not_a_hash_result(value) unless value.is_a?(Hash)
20
24
 
21
- def call(value, options)
22
- return not_a_hash_result(value) unless value.is_a?(Hash)
25
+ validated_hash, key_errors, value_errors = apply_subschemas(value, options)
23
26
 
24
- result, key_errors, value_errors = apply_subschemas(value, options)
27
+ if key_errors.empty? && value_errors.empty?
28
+ Result.success(validated_hash)
29
+ else
30
+ Result.failure(keys: key_errors, values: value_errors)
31
+ end
32
+ end
25
33
 
26
- if key_errors.empty? && value_errors.empty?
27
- Result.success(result)
28
- else
29
- Result.failure(keys: key_errors, values: value_errors)
30
- end
31
- end
34
+ def with_wrapped_subschemas(wrapper)
35
+ self.class.new(
36
+ wrapper.wrap(key_schema),
37
+ wrapper.wrap(value_schema),
38
+ )
39
+ end
32
40
 
33
- def with_wrapped_subschemas(wrapper)
34
- self.class.new(
35
- wrapper.wrap(key_schema),
36
- wrapper.wrap(value_schema),
37
- )
38
- end
41
+ private
39
42
 
40
- private
43
+ def not_a_hash_result(value)
44
+ Result.failure(
45
+ Error.new(
46
+ schema: self,
47
+ value: value,
48
+ symbolic_name: :not_a_hash,
49
+ ),
50
+ )
51
+ end
41
52
 
42
- def not_a_hash_result(value)
43
- Result.failure(Error.new(
44
- schema: self,
45
- value: value,
46
- symbolic_name: :not_a_hash,
47
- ))
48
- end
53
+ def apply_subschemas(value, options)
54
+ validated_hash = {}
55
+ key_errors = {}
56
+ value_errors = {}
49
57
 
50
- def apply_subschemas(value, options)
51
- result = {}
52
- key_errors = {}
53
- value_errors = {}
58
+ value.each do |key, subvalue|
59
+ key_result = key_schema.call(key, options)
60
+ if key_result.invalid?
61
+ key_errors[key] = key_result.error
62
+ break if options.fail_fast?
63
+ end
54
64
 
55
- value.each do |key, subvalue|
56
- key_result = key_schema.call(key, options)
57
- if key_result.invalid?
58
- key_errors[key] = key_result.error
59
- break if options.fail_fast?
60
- end
65
+ subvalue_result = value_schema.call(subvalue, options)
66
+ if subvalue_result.invalid?
67
+ value_errors[key] = subvalue_result.error
68
+ break if options.fail_fast?
69
+ end
61
70
 
62
- subvalue_result = value_schema.call(subvalue, options)
63
- if subvalue_result.invalid?
64
- value_errors[key] = subvalue_result.error
65
- break if options.fail_fast?
71
+ if key_result.valid? && subvalue_result.valid?
72
+ validated_hash[key_result.value] = subvalue_result.value
73
+ end
66
74
  end
67
75
 
68
- if key_result.valid? && subvalue_result.valid?
69
- result[key_result.value] = subvalue_result.value
70
- end
76
+ [validated_hash, key_errors, value_errors]
71
77
  end
72
-
73
- return result, key_errors, value_errors
74
78
  end
75
-
76
- end
77
- end
79
+ end
78
80
  end
@@ -1,60 +1,66 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module RSchema
2
- module Schemas
3
-
4
- #
5
- # A schema that matches variable-length arrays, where all elements conform to
6
- # a single subschema
7
- #
8
- # @example A variable-length array schema
9
- # schema = RSchema.define { array(_Integer) }
10
- # schema.valid?([1,2,3]) #=> true
11
- # schema.valid?([]) #=> true
12
- #
13
- class VariableLengthArray
14
- attr_accessor :element_schema
15
-
16
- def initialize(element_schema)
17
- @element_schema = element_schema
18
- end
4
+ module Schemas
5
+ #
6
+ # A schema that matches variable-length arrays, where all elements conform
7
+ # to a single subschema
8
+ #
9
+ # @example A variable-length array schema
10
+ # schema = RSchema.define { array(_Integer) }
11
+ # schema.valid?([1,2,3]) #=> true
12
+ # schema.valid?([]) #=> true
13
+ #
14
+ class VariableLengthArray
15
+ attr_accessor :element_schema
19
16
 
20
- def call(value, options)
21
- if value.kind_of?(Array)
22
- validated_values, errors = validate_elements(value, options)
23
- if errors.empty?
24
- Result.success(validated_values)
25
- else
26
- Result.failure(errors)
17
+ def initialize(element_schema)
18
+ @element_schema = element_schema
27
19
  end
28
- else
29
- Result.failure(Error.new(
30
- schema: self,
31
- value: value,
32
- symbolic_name: :not_an_array,
33
- ))
34
- end
35
- end
36
20
 
37
- def with_wrapped_subschemas(wrapper)
38
- self.class.new(wrapper.wrap(element_schema))
39
- end
21
+ def call(value, options)
22
+ return type_failure(value) unless value.is_a?(Array)
40
23
 
41
- def validate_elements(array, options)
42
- errors = {}
43
- validated_values = []
44
-
45
- array.each_with_index do |subvalue, idx|
46
- result = @element_schema.call(subvalue, options)
47
- if result.valid?
48
- validated_values[idx] = result.value
49
- else
50
- errors[idx] = result.error
51
- break if options.fail_fast?
24
+ validated_values, errors = validate_elements(value, options)
25
+ if errors.empty?
26
+ Result.success(validated_values)
27
+ else
28
+ Result.failure(errors)
29
+ end
52
30
  end
53
- end
54
31
 
55
- [validated_values, errors]
56
- end
32
+ def with_wrapped_subschemas(wrapper)
33
+ self.class.new(wrapper.wrap(element_schema))
34
+ end
57
35
 
58
- end
59
- end
36
+ private
37
+
38
+ def type_failure(value)
39
+ Result.failure(
40
+ Error.new(
41
+ schema: self,
42
+ value: value,
43
+ symbolic_name: :not_an_array,
44
+ ),
45
+ )
46
+ end
47
+
48
+ def validate_elements(array, options)
49
+ errors = {}
50
+ validated_values = []
51
+
52
+ array.each_with_index do |subvalue, idx|
53
+ result = @element_schema.call(subvalue, options)
54
+ if result.valid?
55
+ validated_values[idx] = result.value
56
+ else
57
+ errors[idx] = result.error
58
+ break if options.fail_fast?
59
+ end
60
+ end
61
+
62
+ [validated_values, errors]
63
+ end
64
+ end
65
+ end
60
66
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module RSchema
2
- VERSION = '3.1.1'
4
+ VERSION = '3.2.0'
3
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rschema
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.1.1
4
+ version: 3.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tom Dalling
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-06-12 00:00:00.000000000 Z
11
+ date: 2017-07-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: docile
@@ -25,77 +25,105 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: '1.1'
27
27
  - !ruby/object:Gem::Dependency
28
- name: rspec
28
+ name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '3.0'
33
+ version: '10.0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '3.0'
40
+ version: '10.0'
41
41
  - !ruby/object:Gem::Dependency
42
- name: rake
42
+ name: gem-release
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '10.0'
47
+ version: '0.7'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '10.0'
54
+ version: '0.7'
55
55
  - !ruby/object:Gem::Dependency
56
- name: gem-release
56
+ name: yard
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rubocop
57
71
  requirement: !ruby/object:Gem::Requirement
58
72
  requirements:
59
73
  - - "~>"
60
74
  - !ruby/object:Gem::Version
61
- version: '0.7'
75
+ version: 0.49.1
62
76
  type: :development
63
77
  prerelease: false
64
78
  version_requirements: !ruby/object:Gem::Requirement
65
79
  requirements:
66
80
  - - "~>"
67
81
  - !ruby/object:Gem::Version
68
- version: '0.7'
82
+ version: 0.49.1
69
83
  - !ruby/object:Gem::Dependency
70
- name: pry
84
+ name: rspec
71
85
  requirement: !ruby/object:Gem::Requirement
72
86
  requirements:
73
- - - ">="
87
+ - - "~>"
74
88
  - !ruby/object:Gem::Version
75
- version: '0'
89
+ version: '3.5'
76
90
  type: :development
77
91
  prerelease: false
78
92
  version_requirements: !ruby/object:Gem::Requirement
79
93
  requirements:
80
- - - ">="
94
+ - - "~>"
81
95
  - !ruby/object:Gem::Version
82
- version: '0'
96
+ version: '3.5'
83
97
  - !ruby/object:Gem::Dependency
84
- name: byebug
98
+ name: rails
85
99
  requirement: !ruby/object:Gem::Requirement
86
100
  requirements:
87
- - - ">="
101
+ - - "~>"
88
102
  - !ruby/object:Gem::Version
89
- version: '0'
103
+ version: '5.1'
90
104
  type: :development
91
105
  prerelease: false
92
106
  version_requirements: !ruby/object:Gem::Requirement
93
107
  requirements:
94
- - - ">="
108
+ - - "~>"
95
109
  - !ruby/object:Gem::Version
96
- version: '0'
110
+ version: '5.1'
97
111
  - !ruby/object:Gem::Dependency
98
- name: yard
112
+ name: rack-test
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: 0.6.3
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: 0.6.3
125
+ - !ruby/object:Gem::Dependency
126
+ name: byebug
99
127
  requirement: !ruby/object:Gem::Requirement
100
128
  requirements:
101
129
  - - ">="
@@ -109,7 +137,7 @@ dependencies:
109
137
  - !ruby/object:Gem::Version
110
138
  version: '0'
111
139
  - !ruby/object:Gem::Dependency
112
- name: benchmark-ips
140
+ name: pry
113
141
  requirement: !ruby/object:Gem::Requirement
114
142
  requirements:
115
143
  - - ">="
@@ -123,7 +151,7 @@ dependencies:
123
151
  - !ruby/object:Gem::Version
124
152
  version: '0'
125
153
  - !ruby/object:Gem::Dependency
126
- name: activemodel
154
+ name: benchmark-ips
127
155
  requirement: !ruby/object:Gem::Requirement
128
156
  requirements:
129
157
  - - ">="
@@ -181,6 +209,7 @@ files:
181
209
  - lib/rschema/dsl.rb
182
210
  - lib/rschema/error.rb
183
211
  - lib/rschema/options.rb
212
+ - lib/rschema/rails.rb
184
213
  - lib/rschema/result.rb
185
214
  - lib/rschema/schemas.rb
186
215
  - lib/rschema/schemas/anything.rb
@@ -211,7 +240,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
211
240
  requirements:
212
241
  - - ">="
213
242
  - !ruby/object:Gem::Version
214
- version: 2.0.0
243
+ version: 2.2.7
215
244
  required_rubygems_version: !ruby/object:Gem::Requirement
216
245
  requirements:
217
246
  - - ">="