dry-schema 1.2.0 → 1.3.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.
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
@@ -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]
@@ -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
@@ -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)
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
203
+ predicates.replace(type_predicates + predicates) unless type_predicates.empty?
210
204
 
211
205
  return self if predicates.empty?
212
206
  end
@@ -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
@@ -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
-
97
- if predicates.first == :nil?
98
- predicates[1..predicates.size - 1]
103
+ if left.eql?(NIL)
104
+ right
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
@@ -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
-
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
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)
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
@@ -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