rschema 3.1.1 → 3.2.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.
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
  - - ">="