checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
---
2
2
SHA256:
3
- metadata.gz: e7dce78efba45d06df82c2de21ab9da5208fef746034e1f3aba396221897540d
4
- data.tar.gz: 85f73e374a58a8110a3d75f1617d3b015b07b0d3f9c44caf4dceced1930d88df
3
+ metadata.gz: c2703b501037f07e55a7018b8e0e048525e591d2f5cb5e369717a0635aacd443
4
+ data.tar.gz: e199bafff541bee970435b2dd26ce10b888c2167d5aec919dafbf91b089311ea
5
5
SHA512:
6
- metadata.gz: b1317319cec5bacf68ec380166226382c4d10818db4b1a575841f04c43b12b2b420877121876ebb13ce85c59b7b88a375c1f9798523cc6fb123e274507203cd2
7
- data.tar.gz: fa995747a3efd66855e6d8cbb7d07e6d2002cd9e459237acc58b8747dd7f7d728d4a5f57482269d25e3c63319110975e8b01ec713536defd31742812dc92e334
6
+ metadata.gz: b7512d9308582c306717a507ad4c218e50137e13699dacadcdb4d9f5d8bb01cfae635cdd78a27d4466e620c13e43d63b4cc7f27112d1bbaf74bdc5e7c7e1d384
7
+ data.tar.gz: 58bc3d577e79752c8495749af8dc9304d1bcae753f6a612fbf744f4dc9586a65aafceb038c9ec6198361edd0b7f930e8f59abd600c74b3ba562de32a5d967e70
data/CHANGELOG.md CHANGED
@@ -1,22 +1,60 @@
1
+ # 1.3.0 2019-07-06
2
+
3
+ ### Added
4
+
5
+ - Automatic predicate inferring for constrained types! (@flash-gordon)
6
+
7
+ ```ruby
8
+ Types::Name = Types::String.constrained(min_size: 1)
9
+
10
+ schema = Dry::Schema.define do
11
+ required(:name).value(Types::Name)
12
+ end
13
+
14
+ schema.(name: '').errors.to_h # => { name: ["size cannot be less than 1"] }
15
+ ```
16
+
17
+ - Support for redefining re-used schemas (issue #43) (@skryukov)
18
+
19
+ ### Fixed
20
+
21
+ - Type container is passed down to nested schemas (@flash-gordon)
22
+
23
+ [Compare v1.2.0...v1.3.0](https://github.com/dry-rb/dry-schema/compare/v1.2.0...v1.3.0)
24
+
1
25
# v1.2.0 2019-06-13
2
26
3
27
### Added
4
28
5
- * Ability to configure your own type container (@Morozzzko)
29
+ - Ability to configure your own type container (@Morozzzko)
30
+
31
+ ```ruby
32
+ types = Dry::Schema::TypeContainer.new
33
+ types.register(
34
+ 'params.trimmed_string',
35
+ Types::String.constructor(&:strip).constructor(&:downcase)
36
+ )
37
+
38
+ Dry::Schema.Params do
39
+ config.types = types
40
+
41
+ require(:name).value(:trimmed_string)
42
+ end
43
+ ```
6
44
7
45
### Fixed
8
46
9
- * `filled` macro no longer generates incorrect messages for arrays (issue #151) (@solnic)
10
- * `filled` macro works correctly with constructor types (@solnic)
11
- * `filled` works correctly with nested schemas (#149) (@solnic + @timriley)
12
- * Custom array constructors are no longer discredited by `array` macro (@solnic)
13
- * `BigDecimal` type is correctly handled by predicate inference (@solnic)
14
- * Works with latest `dry-logic` which provides the new `respond_to?` predicate (#153) (@flash-gordon)
47
+ - `filled` macro no longer generates incorrect messages for arrays (issue #151) (@solnic)
48
+ - `filled` macro works correctly with constructor types (@solnic)
49
+ - `filled` works correctly with nested schemas (#149) (@solnic + @timriley)
50
+ - Custom array constructors are no longer discredited by `array` macro (@solnic)
51
+ - `BigDecimal` type is correctly handled by predicate inference (@solnic)
52
+ - Works with latest `dry-logic` which provides the new `respond_to?` predicate (#153) (@flash-gordon)
15
53
16
54
### Changed
17
55
18
- * Fixes related to `filled` restored pre-1.1.0 behavior of `:hints` which are again included (@solnic)
19
- * `filled` no longer uses filter rules to handle empty strings in `Params` (@solnic)
56
+ - Fixes related to `filled` restored pre-1.1.0 behavior of `:hints` which are again included (@solnic)
57
+ - `filled` no longer uses filter rules to handle empty strings in `Params` (@solnic)
20
58
21
59
[Compare v1.1.0...v1.2.0](https://github.com/dry-rb/dry-schema/compare/v1.1.0...v1.2.0)
22
60
@@ -24,18 +62,18 @@
24
62
25
63
### Added
26
64
27
- * `config.messages.default_locale` for setting...default locale (surprise, surprise) (solnic)
28
- * `Config` exposes `predicates` setting too (solnic)
65
+ - `config.messages.default_locale` for setting...default locale (surprise, surprise) (solnic)
66
+ - `Config` exposes `predicates` setting too (solnic)
29
67
30
68
### Fixed
31
69
32
- * `filled` macro behavior results in `must be filled` error messages when appropriate - see PR #141 for more information (issue #134) (solnic)
33
- * Filter rules no longer cause keys to be added to input (issue #142) (solnic)
34
- * Filter rules work now with inheritance (solnic)
35
- * Inherited type schemas used by coercion are now properly configured as `lax` type (solnic)
36
- * `Config` is now finalized before instantiating schemas and properly dupped when its inherited (flash-gordon + solnic)
37
- * `Config#eql?` works as expected (solnic)
38
- * Predicates are properly inferred from array with a member type spec, ie `array[:integer]` results in `array? + each(:integer?)` (issue #140) (solnic)
70
+ - `filled` macro behavior results in `must be filled` error messages when appropriate - see PR #141 for more information (issue #134) (solnic)
71
+ - Filter rules no longer cause keys to be added to input (issue #142) (solnic)
72
+ - Filter rules work now with inheritance (solnic)
73
+ - Inherited type schemas used by coercion are now properly configured as `lax` type (solnic)
74
+ - `Config` is now finalized before instantiating schemas and properly dupped when its inherited (flash-gordon + solnic)
75
+ - `Config#eql?` works as expected (solnic)
76
+ - Predicates are properly inferred from array with a member type spec, ie `array[:integer]` results in `array? + each(:integer?)` (issue #140) (solnic)
39
77
40
78
[Compare v1.0.3...v1.1.0](https://github.com/dry-rb/dry-schema/compare/v1.0.3...v1.1.0)
41
79
@@ -43,9 +81,9 @@
43
81
44
82
### Fixed
45
83
46
- * `Object#hash` is no longer used to calculate cache keys due to a potential risk of having hash collisions (solnic)
47
- * Predicate arguments are used again for template cache keys (solnic)
48
- * `I18n` messages backend no longer evaluates templates twice (solnic)
84
+ - `Object#hash` is no longer used to calculate cache keys due to a potential risk of having hash collisions (solnic)
85
+ - Predicate arguments are used again for template cache keys (solnic)
86
+ - `I18n` messages backend no longer evaluates templates twice (solnic)
49
87
50
88
[Compare v1.0.2...v1.0.3](https://github.com/dry-rb/dry-schema/compare/v1.0.2...v1.0.3)
51
89
@@ -53,7 +91,7 @@
53
91
54
92
### Fixed
55
93
56
- * Caching message templates uses restricted set of known keys to calculate cache keys (issue #132) (solnic)
94
+ - Caching message templates uses restricted set of known keys to calculate cache keys (issue #132) (solnic)
57
95
58
96
[Compare v1.0.1...v1.0.2](https://github.com/dry-rb/dry-schema/compare/v1.0.1...v1.0.2)
59
97
@@ -61,7 +99,7 @@
61
99
62
100
### Fixed
63
101
64
- * Applying `key?` predicate no longer causes recursive calls to `Result#errors` (issue #130) (solnic)
102
+ - Applying `key?` predicate no longer causes recursive calls to `Result#errors` (issue #130) (solnic)
65
103
66
104
[Compare v1.0.0...v1.0.1](https://github.com/dry-rb/dry-schema/compare/v1.0.0...v1.0.1)
67
105
@@ -69,12 +107,12 @@
69
107
70
108
### Changed
71
109
72
- * [BREAKING] `Result#to_hash` was removed (solnic)
110
+ - [BREAKING] `Result#to_hash` was removed (solnic)
73
111
74
112
### Fixed
75
113
76
- * Setting `:any` as the type spec no longer crashes (solnic)
77
- * `Result#error?` handles paths to array elements correctly (solnic)
114
+ - Setting `:any` as the type spec no longer crashes (solnic)
115
+ - `Result#error?` handles paths to array elements correctly (solnic)
78
116
79
117
[Compare v0.6.0...v1.0.0](https://github.com/dry-rb/dry-schema/compare/v0.6.0...v1.0.0)
80
118
@@ -82,9 +120,9 @@
82
120
83
121
### Changed
84
122
85
- * Dependency on `dry-types` was bumped to `~> 1.0` (solnic)
86
- * Dependency on `dry-logic` was bumped to `~> 1.0` (solnic)
87
- * Dependency on `dry-initializer` was bumped to `~> 3.0` (solnic)
123
+ - Dependency on `dry-types` was bumped to `~> 1.0` (solnic)
124
+ - Dependency on `dry-logic` was bumped to `~> 1.0` (solnic)
125
+ - Dependency on `dry-initializer` was bumped to `~> 3.0` (solnic)
88
126
89
127
[Compare v0.5.1...v0.6.0](https://github.com/dry-rb/dry-schema/compare/v0.5.1...v0.6.0)
90
128
@@ -92,7 +130,7 @@
92
130
93
131
### Fixed
94
132
95
- * Key map no longer crashes on unexpected input (issue #118) (solnic)
133
+ - Key map no longer crashes on unexpected input (issue #118) (solnic)
96
134
97
135
[Compare v0.5.0...v0.5.1](https://github.com/dry-rb/dry-schema/compare/v0.5.0...v0.5.1)
98
136
@@ -100,7 +138,7 @@
100
138
101
139
### Added
102
140
103
- * Support for arbitrary meta-data in messages, ie:
141
+ - Support for arbitrary meta-data in messages, ie:
104
142
105
143
```yaml
106
144
en:
@@ -113,10 +151,10 @@
113
151
114
152
Now your error hash will include `{ foo: [{ text: 'cannot be blank', code: 123 }] }` (solnic + flash-gordon)
115
153
116
- * Support for type specs in `array` macro, ie `required(:tags).array(:integer)` (solnic)
117
- * Support for type specs in `each` macro, ie `required(:tags).each(:integer)` (solnic)
118
- * Shortcut for defining an array with hash as its member, ie:
119
-
154
+ - Support for type specs in `array` macro, ie `required(:tags).array(:integer)` (solnic)
155
+ - Support for type specs in `each` macro, ie `required(:tags).each(:integer)` (solnic)
156
+ - Shortcut for defining an array with hash as its member, ie:
157
+
120
158
```ruby
121
159
Dry::Schema.Params do
122
160
required(:tags).array(:hash) do
@@ -127,13 +165,13 @@
127
165
128
166
### Fixed
129
167
130
- * Inferring predicates doesn't crash when `Any` type is used (flash-gordon)
131
- * Inferring type specs when type is already set works correctly (solnic)
168
+ - Inferring predicates doesn't crash when `Any` type is used (flash-gordon)
169
+ - Inferring type specs when type is already set works correctly (solnic)
132
170
133
171
### Changed
134
172
135
- * [BREAKING] `:monads` extension wraps entire result objects in `Success` or `Failure` (flash-gordon)
136
- * When `:hints` are disabled, result AST will not include hint nodes (solnic)
173
+ - [BREAKING] `:monads` extension wraps entire result objects in `Success` or `Failure` (flash-gordon)
174
+ - When `:hints` are disabled, result AST will not include hint nodes (solnic)
137
175
138
176
[Compare v0.4.0...v0.5.0](https://github.com/dry-rb/dry-schema/compare/v0.4.0...v0.5.0)
139
177
@@ -141,30 +179,30 @@
141
179
142
180
### Added
143
181
144
- * Schemas are now compatible with procs via `#to_proc` (issue #53) (solnic)
145
- * Support for configuring `top_namespace` for localized messages (solnic)
146
- * Support for configuring more than one load path for localized messages (solnic)
147
- * Support for inferring predicates from arbitrary types (issue #101) (solnic)
182
+ - Schemas are now compatible with procs via `#to_proc` (issue #53) (solnic)
183
+ - Support for configuring `top_namespace` for localized messages (solnic)
184
+ - Support for configuring more than one load path for localized messages (solnic)
185
+ - Support for inferring predicates from arbitrary types (issue #101) (solnic)
148
186
149
187
### Fixed
150
188
151
- * Handling of messages for `optional` keys without value rules works correctly (issue #87) (solnic)
152
- * Message structure for `optional` keys with an array of hashes no longer duplicates keys (issue #89) (solnic)
153
- * Inferring `:date_time?` predicate works correctly with `DateTime` types (issue #97) (solnic)
189
+ - Handling of messages for `optional` keys without value rules works correctly (issue #87) (solnic)
190
+ - Message structure for `optional` keys with an array of hashes no longer duplicates keys (issue #89) (solnic)
191
+ - Inferring `:date_time?` predicate works correctly with `DateTime` types (issue #97) (solnic)
154
192
155
193
### Changed
156
194
157
- * [BREAKING] Updated to work with `dry-types 0.15.0` (flash-gordon)
158
- * [BREAKING] `Result#{errors,messages,hints}` returns `MessageSet` object now which is an enumerable coercible to a hash (solnic)
159
- * [BREAKING] `Messages` backend classes no longer use global configuration (solnic)
160
- * [BREAKING] Passing a non-symbol key name in the DSL will raise `ArgumentError` (issue #29) (solnic)
161
- * [BREAKING] Configuration for message backends is now nested under `messages` key with following settings:
162
- * `messages.backend` - previously `messages`
163
- * `messages.load_paths` - previously `messages_path`
164
- * `messages.namespace` - previously `namespace`
165
- * `messages.top_namespace` - **new setting** see above
166
- * [BREAKING] `Messages::I18n` uses `I18.store_translations` instead of messing with `I18n.load_path` (solnic)
167
- * Schemas (`Params` and `JSON`) have nicer inspect (solnic)
195
+ - [BREAKING] Updated to work with `dry-types 0.15.0` (flash-gordon)
196
+ - [BREAKING] `Result#{errors,messages,hints}` returns `MessageSet` object now which is an enumerable coercible to a hash (solnic)
197
+ - [BREAKING] `Messages` backend classes no longer use global configuration (solnic)
198
+ - [BREAKING] Passing a non-symbol key name in the DSL will raise `ArgumentError` (issue #29) (solnic)
199
+ - [BREAKING] Configuration for message backends is now nested under `messages` key with following settings:
200
+ - `messages.backend` - previously `messages`
201
+ - `messages.load_paths` - previously `messages_path`
202
+ - `messages.namespace` - previously `namespace`
203
+ - `messages.top_namespace` - **new setting** see above
204
+ - [BREAKING] `Messages::I18n` uses `I18.store_translations` instead of messing with `I18n.load_path` (solnic)
205
+ - Schemas (`Params` and `JSON`) have nicer inspect (solnic)
168
206
169
207
[Compare v0.3.0...v0.4.0](https://github.com/dry-rb/dry-schema/compare/v0.3.0...v0.4.0)
170
208
@@ -172,16 +210,16 @@
172
210
173
211
### Fixed
174
212
175
- * Configuration is properly inherited from a parent schema (skryukov)
176
- * `Result#error?` returns `true` when a preceding key has errors (solnic)
177
- * Predicate inferrer no longer chokes on sum, constructor and enum types (solnic)
178
- * Predicate inferrer infers `:bool?` from boolean types (solnic)
179
- * Block-based definitions using `array` works correctly (solnic)
180
- * Using a disjunction with `array` and `hash` produces correct errors when element validation for array failed (solnic)
213
+ - Configuration is properly inherited from a parent schema (skryukov)
214
+ - `Result#error?` returns `true` when a preceding key has errors (solnic)
215
+ - Predicate inferrer no longer chokes on sum, constructor and enum types (solnic)
216
+ - Predicate inferrer infers `:bool?` from boolean types (solnic)
217
+ - Block-based definitions using `array` works correctly (solnic)
218
+ - Using a disjunction with `array` and `hash` produces correct errors when element validation for array failed (solnic)
181
219
182
220
### Changed
183
221
184
- * Required ruby version was removed from gemspec for people who are stuck on MRI 2.3.x (solnic)
222
+ - Required ruby version was removed from gemspec for people who are stuck on MRI 2.3.x (solnic)
185
223
186
224
[Compare v0.2.0...v0.3.0](https://github.com/dry-rb/dry-schema/compare/v0.2.0...v0.3.0)
187
225
@@ -189,28 +227,28 @@
189
227
190
228
### Added
191
229
192
- * New `hash` macro which prepends `hash?` type-check and allows nested schema definition (solnic)
193
- * New `array` macro which works like `each` but prepends `array?` type-check (solnic)
230
+ - New `hash` macro which prepends `hash?` type-check and allows nested schema definition (solnic)
231
+ - New `array` macro which works like `each` but prepends `array?` type-check (solnic)
194
232
195
233
### Fixed
196
234
197
- * Rule name translation works correctly with I18n (issue #52) (solnic)
198
- * Rule name translation works correctly with namespaced messages (both I18n and plain YAML) (issue #57) (solnic)
199
- * Error messages under namespaces are correctly resolved for overridden names (issue #53) (solnic)
200
- * Namespaced error messages work correctly when schemas are reused within other schemas (issue #49) (solnic)
201
- * Child schema can override inherited rules now (issue #66) (skryukov)
202
- * Hints are correctly generated for disjunction that use type-check predicates (issue #24) (solnic)
203
- * Hints are correctly generated for nested schemas (issue #26) (solnic)
204
- * `filled` macro respects inferred type-check predicates and puts them in front (solnic)
205
- * Value coercion works correctly with re-usable nested schemas (issue #25) (solnic)
235
+ - Rule name translation works correctly with I18n (issue #52) (solnic)
236
+ - Rule name translation works correctly with namespaced messages (both I18n and plain YAML) (issue #57) (solnic)
237
+ - Error messages under namespaces are correctly resolved for overridden names (issue #53) (solnic)
238
+ - Namespaced error messages work correctly when schemas are reused within other schemas (issue #49) (solnic)
239
+ - Child schema can override inherited rules now (issue #66) (skryukov)
240
+ - Hints are correctly generated for disjunction that use type-check predicates (issue #24) (solnic)
241
+ - Hints are correctly generated for nested schemas (issue #26) (solnic)
242
+ - `filled` macro respects inferred type-check predicates and puts them in front (solnic)
243
+ - Value coercion works correctly with re-usable nested schemas (issue #25) (solnic)
206
244
207
245
### Changed
208
246
209
- * [BREAKING] **Messages are now configured under `dry_schema` namespace by default** (issue #38) (solnic)
210
- * [BREAKING] Hints are now an optional feature provided by `:hints` extension, to load it do `Dry::Schema.load_extensions(:hints)` (solnic)
211
- * [BREAKING] Hints generation was improved in general, output of `Result#messages` and `Result#hints` changed in some cases (solnic)
212
- * [BREAKING] `schema` macro no longer prepends `hash?` check, for this behavior use the new `hash` macro (see #31) (solnic)
213
- * [BREAKING] Support for MRI < 2.4 was dropped (solnic)
247
+ - [BREAKING] **Messages are now configured under `dry_schema` namespace by default** (issue #38) (solnic)
248
+ - [BREAKING] Hints are now an optional feature provided by `:hints` extension, to load it do `Dry::Schema.load_extensions(:hints)` (solnic)
249
+ - [BREAKING] Hints generation was improved in general, output of `Result#messages` and `Result#hints` changed in some cases (solnic)
250
+ - [BREAKING] `schema` macro no longer prepends `hash?` check, for this behavior use the new `hash` macro (see #31) (solnic)
251
+ - [BREAKING] Support for MRI < 2.4 was dropped (solnic)
214
252
215
253
[Compare v0.1.1...v0.2.0](https://github.com/dry-rb/dry-schema/compare/v0.1.1...v0.2.0)
216
254
data/README.md CHANGED
@@ -1,5 +1,5 @@
1
1
[gem]: https://rubygems.org/gems/dry-schema
2
- [travis]: https://travis-ci.org/dry-rb/dry-schema
2
+ [travis]: https://travis-ci.com/dry-rb/dry-schema
3
3
[codeclimate]: https://codeclimate.com/github/dry-rb/dry-schema
4
4
[chat]: https://dry-rb.zulipchat.com
5
5
[inchpages]: http://inch-ci.org/github/dry-rb/dry-schema
@@ -7,7 +7,7 @@
7
7
# dry-schema [![Join the chat at https://dry-rb.zulipchat.com](https://img.shields.io/badge/dry--rb-join%20chat-%23346b7a.svg)][chat]
8
8
9
9
[![Gem Version](https://badge.fury.io/rb/dry-schema.svg)][gem]
10
- [![Build Status](https://travis-ci.org/dry-rb/dry-schema.svg?branch=master)][travis]
10
+ [![Build Status](https://travis-ci.com/dry-rb/dry-schema.svg?branch=master)][travis]
11
11
[![Code Climate](https://codeclimate.com/github/dry-rb/dry-schema/badges/gpa.svg)][codeclimate]
12
12
[![Test Coverage](https://codeclimate.com/github/dry-rb/dry-schema/badges/coverage.svg)][codeclimate]
13
13
[![Inline docs](http://inch-ci.org/github/dry-rb/dry-schema.svg?branch=master)][inchpages]
data/lib/dry/schema/dsl.rb CHANGED
@@ -231,7 +231,7 @@ module Dry
231
231
#
232
232
# @api private
233
233
def new(options = EMPTY_HASH, &block)
234
- self.class.new(options.merge(processor_type: processor_type), &block)
234
+ self.class.new(options.merge(processor_type: processor_type, config: config), &block)
235
235
end
236
236
237
237
# Set a type for the given key name
data/lib/dry/schema/macros/dsl.rb CHANGED
@@ -200,13 +200,7 @@ module Dry
200
200
201
201
type_predicates = predicate_inferrer[resolved_type]
202
202
203
- unless type_predicates.empty? || predicates.include?(type_predicates)
203
+ predicates.replace(type_predicates + predicates) unless type_predicates.empty?
204
- if type_predicates.is_a?(::Array) && type_predicates.size.equal?(1)
205
- predicates.unshift(type_predicates[0])
206
- else
207
- predicates.unshift(type_predicates)
208
- end
209
- end
210
204
211
205
return self if predicates.empty?
212
206
end
data/lib/dry/schema/macros/schema.rb CHANGED
@@ -11,10 +11,10 @@ module Dry
11
11
class Schema < Value
12
12
# @api private
13
13
def call(*args, &block)
14
- super(*args) unless args.empty?
14
+ super(*args, &nil) unless args.empty?
15
15
16
16
if block
17
- schema = define(&block)
17
+ schema = define(*args, &block)
18
18
trace << schema.to_rule
19
19
end
20
20
@@ -24,11 +24,17 @@ module Dry
24
24
private
25
25
26
26
# @api private
27
- def define(&block)
27
+ def define(*args, &block)
28
28
definition = schema_dsl.new(&block)
29
29
schema = definition.call
30
-
31
- type_schema = array? ? parent_type.of(definition.type_schema) : definition.type_schema
30
+ type_schema =
31
+ if array?
32
+ parent_type.of(definition.type_schema)
33
+ elsif redefined_schema?(args)
34
+ parent_type.schema(definition.types)
35
+ else
36
+ definition.type_schema
37
+ end
32
38
final_type = optional? ? type_schema.optional : type_schema
33
39
34
40
type(final_type)
@@ -54,6 +60,16 @@ module Dry
54
60
def array?
55
61
parent_type.respond_to?(:of)
56
62
end
63
+
64
+ # @api private
65
+ def schema?
66
+ parent_type.respond_to?(:schema)
67
+ end
68
+
69
+ # @api private
70
+ def redefined_schema?(args)
71
+ schema? && args.first.is_a?(Processor)
72
+ end
57
73
end
58
74
end
59
75
end
data/lib/dry/schema/predicate_inferrer.rb CHANGED
@@ -22,9 +22,15 @@ module Dry
22
22
}.freeze
23
23
24
24
REDUCED_TYPES = {
25
- %i[true? false?] => :bool?
25
+ [[[:true?], [:false?]]] => %i[bool?]
26
26
}.freeze
27
27
28
+ HASH = %i[hash?].freeze
29
+
30
+ ARRAY = %i[array?].freeze
31
+
32
+ NIL = %i[nil?].freeze
33
+
28
34
# Compiler reduces type AST into a list of predicates
29
35
#
30
36
# @api private
@@ -40,7 +46,7 @@ module Dry
40
46
41
47
# @api private
42
48
def infer_predicate(type)
43
- TYPE_TO_PREDICATE.fetch(type) { :"#{type.name.split('::').last.downcase}?" }
49
+ [TYPE_TO_PREDICATE.fetch(type) { :"#{type.name.split('::').last.downcase}?" }]
44
50
end
45
51
46
52
# @api private
@@ -54,21 +60,21 @@ module Dry
54
60
type = node[0]
55
61
predicate = infer_predicate(type)
56
62
57
- if registry.key?(predicate)
63
+ if registry.key?(predicate[0])
58
64
predicate
59
65
else
60
- { type?: type }
66
+ [type?: type]
61
67
end
62
68
end
63
69
64
70
# @api private
65
71
def visit_hash(_)
66
- :hash?
72
+ HASH
67
73
end
68
74
69
75
# @api private
70
76
def visit_array(_)
71
- :array?
77
+ ARRAY
72
78
end
73
79
74
80
# @api private
@@ -90,26 +96,73 @@ module Dry
90
96
91
97
# @api private
92
98
def visit_sum(node)
93
- left, right = node
99
+ left_node, right_node, = node
100
+ left = visit(left_node)
101
+ right = visit(right_node)
94
102
95
- predicates = [visit(left), visit(right)]
96
-
103
+ if left.eql?(NIL)
104
+ right
97
- if predicates.first == :nil?
98
- predicates[1..predicates.size - 1]
99
105
else
100
- predicates
106
+ [[left, right]]
101
107
end
102
108
end
103
109
104
110
# @api private
105
111
def visit_constrained(node)
106
- other, * = node
107
- visit(other)
112
+ other, rules = node
113
+ predicates = visit(rules)
114
+
115
+ if predicates.empty?
116
+ visit(other)
117
+ else
118
+ [*visit(other), *merge_predicates(predicates)]
119
+ end
108
120
end
109
121
110
122
# @api private
111
123
def visit_any(_)
112
- nil
124
+ EMPTY_ARRAY
125
+ end
126
+
127
+ # @api private
128
+ def visit_and(node)
129
+ left, right = node
130
+ visit(left) + visit(right)
131
+ end
132
+
133
+ # @api private
134
+ def visit_predicate(node)
135
+ pred, args = node
136
+
137
+ if pred.equal?(:type?)
138
+ EMPTY_ARRAY
139
+ elsif registry.key?(pred)
140
+ *curried, _ = args
141
+ values = curried.map { |_, v| v }
142
+
143
+ if values.empty?
144
+ [pred]
145
+ else
146
+ [pred => values[0]]
147
+ end
148
+ else
149
+ EMPTY_ARRAY
150
+ end
151
+ end
152
+
153
+ private
154
+
155
+ # @api private
156
+ def merge_predicates(nodes)
157
+ preds, merged = nodes.each_with_object([[], {}]) do |predicate, (ps, h)|
158
+ if predicate.is_a?(::Hash)
159
+ h.update(predicate)
160
+ else
161
+ ps << predicate
162
+ end
163
+ end
164
+
165
+ merged.empty? ? preds : [*preds, merged]
113
166
end
114
167
end
115
168
@@ -134,7 +187,7 @@ module Dry
134
187
if predicates.is_a?(Hash)
135
188
predicates
136
189
else
137
- Array(REDUCED_TYPES[predicates] || predicates).flatten
190
+ REDUCED_TYPES[predicates] || predicates
138
191
end
139
192
end
140
193
end
data/lib/dry/schema/trace.rb CHANGED
@@ -29,33 +29,28 @@ module Dry
29
29
end
30
30
31
31
# @api private
32
- def evaluate(*predicates, **opts)
33
- pred_opts = opts.dup
34
- pred_opts.delete(:type_spec)
35
-
32
+ def evaluate(*args, type_spec: ::Dry::Schema::Undefined, **opts)
33
+ predicates = opts.empty? ? args : args.push(opts)
34
+ evaluate_predicates(predicates).each do |rule|
35
+ append(rule)
36
- predicates.each do |predicate|
37
- if predicate.respond_to?(:call)
38
- append(predicate)
39
- elsif predicate.is_a?(::Hash)
40
- evaluate_hash_predicates(predicate)
41
- elsif predicate.is_a?(::Array)
42
- append(predicate.map { |pred| __send__(pred) }.reduce(:|))
43
- else
44
- append(__send__(predicate))
45
- end
46
36
end
47
37
48
- evaluate_hash_predicates(pred_opts)
49
-
50
38
self
51
39
end
52
40
53
41
# @api private
54
- def evaluate_hash_predicates(predicates)
55
- predicates.each do |predicate, *args|
56
- append(__send__(predicate, *args))
42
+ def evaluate_predicates(predicates)
43
+ predicates.flat_map do |predicate|
44
+ if predicate.respond_to?(:call)
45
+ predicate
46
+ elsif predicate.is_a?(::Array)
47
+ predicate.map { |pred| evaluate_predicates(pred).reduce(:&) }.reduce(:|)
48
+ elsif predicate.is_a?(::Hash)
49
+ predicate.map { |pred, *args| __send__(pred, *args) }
50
+ else
51
+ __send__(predicate)
52
+ end
57
53
end
58
- self
59
54
end
60
55
61
56
# @api private
data/lib/dry/schema/version.rb CHANGED
@@ -2,6 +2,6 @@
2
2
3
3
module Dry
4
4
module Schema
5
- VERSION = '1.2.0'
5
+ VERSION = '1.3.0'
6
6
end
7
7
end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
--- !ruby/object:Gem::Specification
2
2
name: dry-schema
3
3
version: !ruby/object:Gem::Version
4
- version: 1.2.0
4
+ version: 1.3.0
5
5
platform: ruby
6
6
authors:
7
7
- Piotr Solnica
8
8
autorequire:
9
9
bindir: bin
10
10
cert_chain: []
11
- date: 2019-06-13 00:00:00.000000000 Z
11
+ date: 2019-07-06 00:00:00.000000000 Z
12
12
dependencies:
13
13
- !ruby/object:Gem::Dependency
14
14
name: concurrent-ruby