dry-schema 1.3.4 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9efbd58d7d7d70ec01d578de507f1fc6ba3e78bfeb81e30e8b69a2ca29fbc753
4
- data.tar.gz: 874370eec0e97f1b87bee9a18d606a45b0aba4d80729c7637407147f4f01a7fc
3
+ metadata.gz: 8bf30b15bfb1d11c70a14898fe9ac7d9cb74f46f70b5a26b1e08cf6568414160
4
+ data.tar.gz: fcd0fc1691ffe1e2b2f5129710fa920daf7ec968749625e050fba3ee9a2a7f73
5
5
  SHA512:
6
- metadata.gz: 8b23a5b75861ef7f9c9ab8430439f580877788c98f79268913723e9fea653df7aaf3fc074839ce561b42c8f7268f9a22069e0a7c8c3f71b20f9cdd4956df1aad
7
- data.tar.gz: ee1987669c04d04b93d20d1a975c2418b8cf9b355caf96a313f9a7f4b50d60514ec2071af82d263f0972fc3c24c865c3fb67b7073a914a3dce1636ce958ea455
6
+ metadata.gz: 7d5a852339e072be3b033268ed826d75a319cf0c33f279e507fc80d6a3ba079370bd7e2859d3aaa5dba786e85521f9c328cf5107f941fa05f422d0bd1a8250af
7
+ data.tar.gz: f1e95d4206bc7f45ccc8a5018c14f52f20db4c314509d2eedf72a67284cd574f43ee8d73ec071b7325be0512b87269043d1d488ab63c437fd767032907b0183f
@@ -1,8 +1,29 @@
1
+ # 1.4.0 2019-10-08
2
+
3
+ ### Added
4
+
5
+ - Support for passing multiple parent schemas. They are inherited from left to right (@ianwhite)
6
+
7
+ ```ruby
8
+ Dry::Schema.define(parent: [parent_a, parent_b, parent_c]) do
9
+ ...
10
+ end
11
+ ```
12
+
13
+ - Improved error messages about missing translations (@skryukov)
14
+ - [experimental] before/after callbacks for schema steps (@skryukov)
15
+
16
+ ### Fixed
17
+
18
+ - Added/fixed support for custom optional types (@flash-gordon)
19
+
20
+ [Compare v1.3.4...v1.4.0](https://github.com/dry-rb/dry-schema/compare/v1.3.4...v1.4.0)
21
+
1
22
  # 1.3.4 2019-09-11
2
23
 
3
24
  ### Fixed
4
25
 
5
- * Fixed regression where using `array?` predicate within a block would crach (issue #186) (@skryukov)
26
+ - Fixed regression where using `array?` predicate within a block would crach (issue #186) (@skryukov)
6
27
 
7
28
  [Compare v1.3.3...v1.3.4](https://github.com/dry-rb/dry-schema/compare/v1.3.3...v1.3.4)
8
29
 
@@ -10,10 +31,10 @@
10
31
 
11
32
  ### Fixed
12
33
 
13
- * Reject attempts to build a nested schema for array types built on `Dry::Types::Nominal` (fixed #171) (@flash-gordon)
14
- * Current `I18n.locale` is now properly handled when caching message templates (@flash-gordon)
15
- * Default processor uses strict types by default, which fixes various cases when `maybe` is used with a constructor type (@flash-gordon)
16
- * Namespaced messages no longer causes a crash when used with nested schemas (fixed #176) (@solnic)
34
+ - Reject attempts to build a nested schema for array types built on `Dry::Types::Nominal` (fixed #171) (@flash-gordon)
35
+ - Current `I18n.locale` is now properly handled when caching message templates (@flash-gordon)
36
+ - Default processor uses strict types by default, which fixes various cases when `maybe` is used with a constructor type (@flash-gordon)
37
+ - Namespaced messages no longer causes a crash when used with nested schemas (fixed #176) (@solnic)
17
38
 
18
39
  [Compare v1.3.2...v1.3.3](https://github.com/dry-rb/dry-schema/compare/v1.3.2...v1.3.3)
19
40
 
@@ -21,7 +42,7 @@
21
42
 
22
43
  ### Added
23
44
 
24
- * Support for new predicates: `bytesize?`, `min_bytesize?` and `max_bytesize?` (@bmalinconico)
45
+ - Support for new predicates: `bytesize?`, `min_bytesize?` and `max_bytesize?` (@bmalinconico)
25
46
 
26
47
  [Compare v1.3.1...v1.3.2](https://github.com/dry-rb/dry-schema/compare/v1.3.1...v1.3.2)
27
48
 
@@ -29,8 +50,8 @@
29
50
 
30
51
  ### Fixed
31
52
 
32
- * `Result#error?` works correctly with nested hashes and arrays (@solnic)
33
- * `:hints` extension no longer causes a crash where base messages are generated too (issue #165) (@solnic)
53
+ - `Result#error?` works correctly with nested hashes and arrays (@solnic)
54
+ - `:hints` extension no longer causes a crash where base messages are generated too (issue #165) (@solnic)
34
55
 
35
56
  [Compare v1.3.0...v1.3.1](https://github.com/dry-rb/dry-schema/compare/v1.3.0...v1.3.1)
36
57
 
@@ -40,15 +61,15 @@
40
61
 
41
62
  - Automatic predicate inferring for constrained types! (@flash-gordon)
42
63
 
43
- ```ruby
44
- Types::Name = Types::String.constrained(min_size: 1)
64
+ ```ruby
65
+ Types::Name = Types::String.constrained(min_size: 1)
45
66
 
46
- schema = Dry::Schema.define do
47
- required(:name).value(Types::Name)
48
- end
67
+ schema = Dry::Schema.define do
68
+ required(:name).value(Types::Name)
69
+ end
49
70
 
50
- schema.(name: '').errors.to_h # => { name: ["size cannot be less than 1"] }
51
- ```
71
+ schema.(name: '').errors.to_h # => { name: ["size cannot be less than 1"] }
72
+ ```
52
73
 
53
74
  - Support for redefining re-used schemas (issue #43) (@skryukov)
54
75
 
@@ -64,19 +85,19 @@
64
85
 
65
86
  - Ability to configure your own type container (@Morozzzko)
66
87
 
67
- ```ruby
68
- types = Dry::Schema::TypeContainer.new
69
- types.register(
70
- 'params.trimmed_string',
71
- Types::String.constructor(&:strip).constructor(&:downcase)
72
- )
88
+ ```ruby
89
+ types = Dry::Schema::TypeContainer.new
90
+ types.register(
91
+ 'params.trimmed_string',
92
+ Types::String.constructor(&:strip).constructor(&:downcase)
93
+ )
73
94
 
74
- Dry::Schema.Params do
75
- config.types = types
95
+ Dry::Schema.Params do
96
+ config.types = types
76
97
 
77
- require(:name).value(:trimmed_string)
78
- end
79
- ```
98
+ require(:name).value(:trimmed_string)
99
+ end
100
+ ```
80
101
 
81
102
  ### Fixed
82
103
 
@@ -98,18 +119,18 @@
98
119
 
99
120
  ### Added
100
121
 
101
- - `config.messages.default_locale` for setting...default locale (surprise, surprise) (solnic)
102
- - `Config` exposes `predicates` setting too (solnic)
122
+ - `config.messages.default_locale` for setting...default locale (surprise, surprise) (@solnic)
123
+ - `Config` exposes `predicates` setting too (@solnic)
103
124
 
104
125
  ### Fixed
105
126
 
106
- - `filled` macro behavior results in `must be filled` error messages when appropriate - see PR #141 for more information (issue #134) (solnic)
107
- - Filter rules no longer cause keys to be added to input (issue #142) (solnic)
108
- - Filter rules work now with inheritance (solnic)
109
- - Inherited type schemas used by coercion are now properly configured as `lax` type (solnic)
110
- - `Config` is now finalized before instantiating schemas and properly dupped when its inherited (flash-gordon + solnic)
111
- - `Config#eql?` works as expected (solnic)
112
- - Predicates are properly inferred from array with a member type spec, ie `array[:integer]` results in `array? + each(:integer?)` (issue #140) (solnic)
127
+ - `filled` macro behavior results in `must be filled` error messages when appropriate - see PR #141 for more information (issue #134) (@solnic)
128
+ - Filter rules no longer cause keys to be added to input (issue #142) (@solnic)
129
+ - Filter rules work now with inheritance (@solnic)
130
+ - Inherited type schemas used by coercion are now properly configured as `lax` type (@solnic)
131
+ - `Config` is now finalized before instantiating schemas and properly dupped when its inherited (@flash-gordon + @solnic)
132
+ - `Config#eql?` works as expected (@solnic)
133
+ - Predicates are properly inferred from array with a member type spec, ie `array[:integer]` results in `array? + each(:integer?)` (issue #140) (@solnic)
113
134
 
114
135
  [Compare v1.0.3...v1.1.0](https://github.com/dry-rb/dry-schema/compare/v1.0.3...v1.1.0)
115
136
 
@@ -117,9 +138,9 @@
117
138
 
118
139
  ### Fixed
119
140
 
120
- - `Object#hash` is no longer used to calculate cache keys due to a potential risk of having hash collisions (solnic)
121
- - Predicate arguments are used again for template cache keys (solnic)
122
- - `I18n` messages backend no longer evaluates templates twice (solnic)
141
+ - `Object#hash` is no longer used to calculate cache keys due to a potential risk of having hash collisions (@solnic)
142
+ - Predicate arguments are used again for template cache keys (@solnic)
143
+ - `I18n` messages backend no longer evaluates templates twice (@solnic)
123
144
 
124
145
  [Compare v1.0.2...v1.0.3](https://github.com/dry-rb/dry-schema/compare/v1.0.2...v1.0.3)
125
146
 
@@ -127,7 +148,7 @@
127
148
 
128
149
  ### Fixed
129
150
 
130
- - Caching message templates uses restricted set of known keys to calculate cache keys (issue #132) (solnic)
151
+ - Caching message templates uses restricted set of known keys to calculate cache keys (issue #132) (@solnic)
131
152
 
132
153
  [Compare v1.0.1...v1.0.2](https://github.com/dry-rb/dry-schema/compare/v1.0.1...v1.0.2)
133
154
 
@@ -135,7 +156,7 @@
135
156
 
136
157
  ### Fixed
137
158
 
138
- - Applying `key?` predicate no longer causes recursive calls to `Result#errors` (issue #130) (solnic)
159
+ - Applying `key?` predicate no longer causes recursive calls to `Result#errors` (issue #130) (@solnic)
139
160
 
140
161
  [Compare v1.0.0...v1.0.1](https://github.com/dry-rb/dry-schema/compare/v1.0.0...v1.0.1)
141
162
 
@@ -143,12 +164,12 @@
143
164
 
144
165
  ### Changed
145
166
 
146
- - [BREAKING] `Result#to_hash` was removed (solnic)
167
+ - [BREAKING] `Result#to_hash` was removed (@solnic)
147
168
 
148
169
  ### Fixed
149
170
 
150
- - Setting `:any` as the type spec no longer crashes (solnic)
151
- - `Result#error?` handles paths to array elements correctly (solnic)
171
+ - Setting `:any` as the type spec no longer crashes (@solnic)
172
+ - `Result#error?` handles paths to array elements correctly (@solnic)
152
173
 
153
174
  [Compare v0.6.0...v1.0.0](https://github.com/dry-rb/dry-schema/compare/v0.6.0...v1.0.0)
154
175
 
@@ -156,9 +177,9 @@
156
177
 
157
178
  ### Changed
158
179
 
159
- - Dependency on `dry-types` was bumped to `~> 1.0` (solnic)
160
- - Dependency on `dry-logic` was bumped to `~> 1.0` (solnic)
161
- - Dependency on `dry-initializer` was bumped to `~> 3.0` (solnic)
180
+ - Dependency on `dry-types` was bumped to `~> 1.0` (@solnic)
181
+ - Dependency on `dry-logic` was bumped to `~> 1.0` (@solnic)
182
+ - Dependency on `dry-initializer` was bumped to `~> 3.0` (@solnic)
162
183
 
163
184
  [Compare v0.5.1...v0.6.0](https://github.com/dry-rb/dry-schema/compare/v0.5.1...v0.6.0)
164
185
 
@@ -166,7 +187,7 @@
166
187
 
167
188
  ### Fixed
168
189
 
169
- - Key map no longer crashes on unexpected input (issue #118) (solnic)
190
+ - Key map no longer crashes on unexpected input (issue #118) (@solnic)
170
191
 
171
192
  [Compare v0.5.0...v0.5.1](https://github.com/dry-rb/dry-schema/compare/v0.5.0...v0.5.1)
172
193
 
@@ -176,38 +197,38 @@
176
197
 
177
198
  - Support for arbitrary meta-data in messages, ie:
178
199
 
179
- ```yaml
180
- en:
181
- dry_schema:
182
- errors:
183
- filled?:
184
- text: "cannot be blank"
185
- code: 123
186
- ```
200
+ ```yaml
201
+ en:
202
+ dry_schema:
203
+ errors:
204
+ filled?:
205
+ text: "cannot be blank"
206
+ code: 123
207
+ ```
187
208
 
188
- Now your error hash will include `{ foo: [{ text: 'cannot be blank', code: 123 }] }` (solnic + flash-gordon)
209
+ Now your error hash will include `{ foo: [{ text: 'cannot be blank', code: 123 }] }` (@solnic + @flash-gordon)
189
210
 
190
- - Support for type specs in `array` macro, ie `required(:tags).array(:integer)` (solnic)
191
- - Support for type specs in `each` macro, ie `required(:tags).each(:integer)` (solnic)
211
+ - Support for type specs in `array` macro, ie `required(:tags).array(:integer)` (@solnic)
212
+ - Support for type specs in `each` macro, ie `required(:tags).each(:integer)` (@solnic)
192
213
  - Shortcut for defining an array with hash as its member, ie:
193
214
 
194
- ```ruby
195
- Dry::Schema.Params do
196
- required(:tags).array(:hash) do
197
- required(:name).filled(:string)
198
- end
199
- end
200
- ```
215
+ ```ruby
216
+ Dry::Schema.Params do
217
+ required(:tags).array(:hash) do
218
+ required(:name).filled(:string)
219
+ end
220
+ end
221
+ ```
201
222
 
202
223
  ### Fixed
203
224
 
204
- - Inferring predicates doesn't crash when `Any` type is used (flash-gordon)
205
- - Inferring type specs when type is already set works correctly (solnic)
225
+ - Inferring predicates doesn't crash when `Any` type is used (@flash-gordon)
226
+ - Inferring type specs when type is already set works correctly (@solnic)
206
227
 
207
228
  ### Changed
208
229
 
209
- - [BREAKING] `:monads` extension wraps entire result objects in `Success` or `Failure` (flash-gordon)
210
- - When `:hints` are disabled, result AST will not include hint nodes (solnic)
230
+ - [BREAKING] `:monads` extension wraps entire result objects in `Success` or `Failure` (@flash-gordon)
231
+ - When `:hints` are disabled, result AST will not include hint nodes (@solnic)
211
232
 
212
233
  [Compare v0.4.0...v0.5.0](https://github.com/dry-rb/dry-schema/compare/v0.4.0...v0.5.0)
213
234
 
@@ -215,30 +236,30 @@
215
236
 
216
237
  ### Added
217
238
 
218
- - Schemas are now compatible with procs via `#to_proc` (issue #53) (solnic)
219
- - Support for configuring `top_namespace` for localized messages (solnic)
220
- - Support for configuring more than one load path for localized messages (solnic)
221
- - Support for inferring predicates from arbitrary types (issue #101) (solnic)
239
+ - Schemas are now compatible with procs via `#to_proc` (issue #53) (@solnic)
240
+ - Support for configuring `top_namespace` for localized messages (@solnic)
241
+ - Support for configuring more than one load path for localized messages (@solnic)
242
+ - Support for inferring predicates from arbitrary types (issue #101) (@solnic)
222
243
 
223
244
  ### Fixed
224
245
 
225
- - Handling of messages for `optional` keys without value rules works correctly (issue #87) (solnic)
226
- - Message structure for `optional` keys with an array of hashes no longer duplicates keys (issue #89) (solnic)
227
- - Inferring `:date_time?` predicate works correctly with `DateTime` types (issue #97) (solnic)
246
+ - Handling of messages for `optional` keys without value rules works correctly (issue #87) (@solnic)
247
+ - Message structure for `optional` keys with an array of hashes no longer duplicates keys (issue #89) (@solnic)
248
+ - Inferring `:date_time?` predicate works correctly with `DateTime` types (issue #97) (@solnic)
228
249
 
229
250
  ### Changed
230
251
 
231
- - [BREAKING] Updated to work with `dry-types 0.15.0` (flash-gordon)
232
- - [BREAKING] `Result#{errors,messages,hints}` returns `MessageSet` object now which is an enumerable coercible to a hash (solnic)
233
- - [BREAKING] `Messages` backend classes no longer use global configuration (solnic)
234
- - [BREAKING] Passing a non-symbol key name in the DSL will raise `ArgumentError` (issue #29) (solnic)
252
+ - [BREAKING] Updated to work with `dry-types 0.15.0` (@flash-gordon)
253
+ - [BREAKING] `Result#{errors,messages,hints}` returns `MessageSet` object now which is an enumerable coercible to a hash (@solnic)
254
+ - [BREAKING] `Messages` backend classes no longer use global configuration (@solnic)
255
+ - [BREAKING] Passing a non-symbol key name in the DSL will raise `ArgumentError` (issue #29) (@solnic)
235
256
  - [BREAKING] Configuration for message backends is now nested under `messages` key with following settings:
236
- - `messages.backend` - previously `messages`
237
- - `messages.load_paths` - previously `messages_path`
238
- - `messages.namespace` - previously `namespace`
239
- - `messages.top_namespace` - **new setting** see above
240
- - [BREAKING] `Messages::I18n` uses `I18.store_translations` instead of messing with `I18n.load_path` (solnic)
241
- - Schemas (`Params` and `JSON`) have nicer inspect (solnic)
257
+ - `messages.backend` - previously `messages`
258
+ - `messages.load_paths` - previously `messages_path`
259
+ - `messages.namespace` - previously `namespace`
260
+ - `messages.top_namespace` - **new setting** see above
261
+ - [BREAKING] `Messages::I18n` uses `I18.store_translations` instead of messing with `I18n.load_path` (@solnic)
262
+ - Schemas (`Params` and `JSON`) have nicer inspect (@solnic)
242
263
 
243
264
  [Compare v0.3.0...v0.4.0](https://github.com/dry-rb/dry-schema/compare/v0.3.0...v0.4.0)
244
265
 
@@ -246,16 +267,16 @@
246
267
 
247
268
  ### Fixed
248
269
 
249
- - Configuration is properly inherited from a parent schema (skryukov)
250
- - `Result#error?` returns `true` when a preceding key has errors (solnic)
251
- - Predicate inferrer no longer chokes on sum, constructor and enum types (solnic)
252
- - Predicate inferrer infers `:bool?` from boolean types (solnic)
253
- - Block-based definitions using `array` works correctly (solnic)
254
- - Using a disjunction with `array` and `hash` produces correct errors when element validation for array failed (solnic)
270
+ - Configuration is properly inherited from a parent schema (@skryukov)
271
+ - `Result#error?` returns `true` when a preceding key has errors (@solnic)
272
+ - Predicate inferrer no longer chokes on sum, constructor and enum types (@solnic)
273
+ - Predicate inferrer infers `:bool?` from boolean types (@solnic)
274
+ - Block-based definitions using `array` works correctly (@solnic)
275
+ - Using a disjunction with `array` and `hash` produces correct errors when element validation for array failed (@solnic)
255
276
 
256
277
  ### Changed
257
278
 
258
- - Required ruby version was removed from gemspec for people who are stuck on MRI 2.3.x (solnic)
279
+ - Required ruby version was removed from gemspec for people who are stuck on MRI 2.3.x (@solnic)
259
280
 
260
281
  [Compare v0.2.0...v0.3.0](https://github.com/dry-rb/dry-schema/compare/v0.2.0...v0.3.0)
261
282
 
@@ -263,28 +284,28 @@
263
284
 
264
285
  ### Added
265
286
 
266
- - New `hash` macro which prepends `hash?` type-check and allows nested schema definition (solnic)
267
- - New `array` macro which works like `each` but prepends `array?` type-check (solnic)
287
+ - New `hash` macro which prepends `hash?` type-check and allows nested schema definition (@solnic)
288
+ - New `array` macro which works like `each` but prepends `array?` type-check (@solnic)
268
289
 
269
290
  ### Fixed
270
291
 
271
- - Rule name translation works correctly with I18n (issue #52) (solnic)
272
- - Rule name translation works correctly with namespaced messages (both I18n and plain YAML) (issue #57) (solnic)
273
- - Error messages under namespaces are correctly resolved for overridden names (issue #53) (solnic)
274
- - Namespaced error messages work correctly when schemas are reused within other schemas (issue #49) (solnic)
275
- - Child schema can override inherited rules now (issue #66) (skryukov)
276
- - Hints are correctly generated for disjunction that use type-check predicates (issue #24) (solnic)
277
- - Hints are correctly generated for nested schemas (issue #26) (solnic)
278
- - `filled` macro respects inferred type-check predicates and puts them in front (solnic)
279
- - Value coercion works correctly with re-usable nested schemas (issue #25) (solnic)
292
+ - Rule name translation works correctly with I18n (issue #52) (@solnic)
293
+ - Rule name translation works correctly with namespaced messages (both I18n and plain YAML) (issue #57) (@solnic)
294
+ - Error messages under namespaces are correctly resolved for overridden names (issue #53) (@solnic)
295
+ - Namespaced error messages work correctly when schemas are reused within other schemas (issue #49) (@solnic)
296
+ - Child schema can override inherited rules now (issue #66) (@skryukov)
297
+ - Hints are correctly generated for disjunction that use type-check predicates (issue #24) (@solnic)
298
+ - Hints are correctly generated for nested schemas (issue #26) (@solnic)
299
+ - `filled` macro respects inferred type-check predicates and puts them in front (@solnic)
300
+ - Value coercion works correctly with re-usable nested schemas (issue #25) (@solnic)
280
301
 
281
302
  ### Changed
282
303
 
283
- - [BREAKING] **Messages are now configured under `dry_schema` namespace by default** (issue #38) (solnic)
284
- - [BREAKING] Hints are now an optional feature provided by `:hints` extension, to load it do `Dry::Schema.load_extensions(:hints)` (solnic)
285
- - [BREAKING] Hints generation was improved in general, output of `Result#messages` and `Result#hints` changed in some cases (solnic)
286
- - [BREAKING] `schema` macro no longer prepends `hash?` check, for this behavior use the new `hash` macro (see #31) (solnic)
287
- - [BREAKING] Support for MRI < 2.4 was dropped (solnic)
304
+ - [BREAKING] **Messages are now configured under `dry_schema` namespace by default** (issue #38) (@solnic)
305
+ - [BREAKING] Hints are now an optional feature provided by `:hints` extension, to load it do `Dry::Schema.load_extensions(:hints)` (@solnic)
306
+ - [BREAKING] Hints generation was improved in general, output of `Result#messages` and `Result#hints` changed in some cases (@solnic)
307
+ - [BREAKING] `schema` macro no longer prepends `hash?` check, for this behavior use the new `hash` macro (see #31) (@solnic)
308
+ - [BREAKING] Support for MRI < 2.4 was dropped (@solnic)
288
309
 
289
310
  [Compare v0.1.1...v0.2.0](https://github.com/dry-rb/dry-schema/compare/v0.1.1...v0.2.0)
290
311
 
@@ -292,16 +313,16 @@
292
313
 
293
314
  ### Added
294
315
 
295
- - `Result#error?` supports checking nested errors too ie`result.error?('user.address')` (solnic)
316
+ - `Result#error?` supports checking nested errors too ie`result.error?('user.address')` (@solnic)
296
317
 
297
318
  ### Fixed
298
319
 
299
- - Fix issues with templates and invalid tokens (issue #27) (solnic)
300
- - Fix Ruby warnings (flash-gordon)
320
+ - Fix issues with templates and invalid tokens (issue #27) (@solnic)
321
+ - Fix Ruby warnings (@flash-gordon)
301
322
 
302
323
  ### Internal
303
324
 
304
- - Key and value coercers are now equalizable (flash-gordon)
325
+ - Key and value coercers are now equalizable (@flash-gordon)
305
326
 
306
327
  [Compare v0.1.0...v0.1.1](https://github.com/dry-rb/dry-schema/compare/v0.1.0...v0.1.1)
307
328
 
data/README.md CHANGED
@@ -1,5 +1,6 @@
1
1
  [gem]: https://rubygems.org/gems/dry-schema
2
2
  [travis]: https://travis-ci.com/dry-rb/dry-schema
3
+ [actions]: https://github.com/dry-rb/dry-schema/actions
3
4
  [codeclimate]: https://codeclimate.com/github/dry-rb/dry-schema
4
5
  [chat]: https://dry-rb.zulipchat.com
5
6
  [inchpages]: http://inch-ci.org/github/dry-rb/dry-schema
@@ -7,7 +8,8 @@
7
8
  # dry-schema [![Join the chat at https://dry-rb.zulipchat.com](https://img.shields.io/badge/dry--rb-join%20chat-%23346b7a.svg)][chat]
8
9
 
9
10
  [![Gem Version](https://badge.fury.io/rb/dry-schema.svg)][gem]
10
- [![Build Status](https://travis-ci.com/dry-rb/dry-schema.svg?branch=master)][travis]
11
+ [![Travis Status](https://travis-ci.com/dry-rb/dry-schema.svg?branch=master)][travis]
12
+ [![CI Status](https://github.com/dry-rb/dry-schema/workflows/ci/badge.svg)][actions]
11
13
  [![Code Climate](https://codeclimate.com/github/dry-rb/dry-schema/badges/gpa.svg)][codeclimate]
12
14
  [![Test Coverage](https://codeclimate.com/github/dry-rb/dry-schema/badges/coverage.svg)][codeclimate]
13
15
  [![Inline docs](http://inch-ci.org/github/dry-rb/dry-schema.svg?branch=master)][inchpages]
@@ -26,10 +26,11 @@ module Dry
26
26
  # An error raised when a localized message cannot be found
27
27
  MissingMessageError = Class.new(StandardError) do
28
28
  # @api private
29
- def initialize(path)
29
+ def initialize(path, paths = [])
30
30
  *rest, rule = path
31
31
  super(<<~STR)
32
- Message template for #{rule.inspect} under #{rest.join(DOT).inspect} was not found
32
+ Message template for #{rule.inspect} under #{rest.join(DOT).inspect} was not found. Searched in:
33
+ #{paths.map { |string| "\"#{string}\"" }.join("\n")}
33
34
  STR
34
35
  end
35
36
  end
@@ -9,6 +9,7 @@ require 'dry/schema/types'
9
9
  require 'dry/schema/macros'
10
10
 
11
11
  require 'dry/schema/processor'
12
+ require 'dry/schema/processor_steps'
12
13
  require 'dry/schema/key_map'
13
14
  require 'dry/schema/key_coercer'
14
15
  require 'dry/schema/value_coercer'
@@ -64,18 +65,21 @@ module Dry
64
65
  # @return [Compiler] A key=>type map defined within the DSL
65
66
  option :types, default: -> { EMPTY_HASH.dup }
66
67
 
67
- # @return [DSL] An optional parent DSL object that will be used to merge keys and rules
68
- option :parent, optional: true
68
+ # @return [Array] Optional parent DSL objects, that will be used to merge keys and rules
69
+ option :parent, Types::Coercible::Array, default: -> { EMPTY_ARRAY.dup }, as: :parents
69
70
 
70
71
  # @return [Config] Configuration object exposed via `#configure` method
71
72
  option :config, optional: true, default: proc { parent ? parent.config.dup : Config.new }
72
73
 
74
+ # @return [ProcessorSteps] Steps for the processor
75
+ option :steps, default: proc { parent ? parent.steps.dup : ProcessorSteps.new }
76
+
73
77
  # Build a new DSL object and evaluate provided block
74
78
  #
75
79
  # @param [Hash] options
76
80
  # @option options [Class] :processor The processor type (`Params`, `JSON` or a custom sub-class)
77
81
  # @option options [Compiler] :compiler An instance of a rule compiler (must be compatible with `Schema::Compiler`) (optional)
78
- # @option options [DSL] :parent An instance of the parent DSL (optional)
82
+ # @option options [Array[DSL]] :parent One or more instances of the parent DSL (optional)
79
83
  # @option options [Config] :config A configuration object (optional)
80
84
  #
81
85
  # @see Schema.define
@@ -189,9 +193,10 @@ module Dry
189
193
  #
190
194
  # @api private
191
195
  def call
192
- steps = [key_coercer]
193
- steps << filter_schema.rule_applier if filter_rules?
194
- steps << value_coercer << rule_applier
196
+ steps[:key_coercer] = key_coercer
197
+ steps[:value_coercer] = value_coercer
198
+ steps[:rule_applier] = rule_applier
199
+ steps[:filter_schema] = filter_schema.rule_applier if filter_rules?
195
200
 
196
201
  processor_type.new(schema_dsl: self, steps: steps)
197
202
  end
@@ -215,14 +220,54 @@ module Dry
215
220
  -> member_type { type_registry['array'].of(resolve_type(member_type)) }
216
221
  end
217
222
 
223
+ # Method allows steps injection to the processor
224
+ #
225
+ # @example
226
+ # before(:rule_applier) do |input|
227
+ # input.compact
228
+ # end
229
+ #
230
+ # @return [DSL]
231
+ #
232
+ # @api public
233
+ def before(key, &block)
234
+ steps.before(key, &block)
235
+ self
236
+ end
237
+
238
+ # Method allows steps injection to the processor
239
+ #
240
+ # @example
241
+ # after(:rule_applier) do |input|
242
+ # input.compact
243
+ # end
244
+ #
245
+ # @return [DSL]
246
+ #
247
+ # @api public
248
+ def after(key, &block)
249
+ steps.after(key, &block)
250
+ self
251
+ end
252
+
253
+ # The parent (last from parents) which is used for copying non mergeable configuration
254
+ #
255
+ # @return DSL
256
+ #
257
+ # @api public
258
+ def parent
259
+ @parent ||= parents.last
260
+ end
261
+
218
262
  # Return type schema used by the value coercer
219
263
  #
220
264
  # @return [Dry::Types::Safe]
221
265
  #
222
266
  # @api private
223
267
  def type_schema
224
- schema = type_registry['hash'].schema(types).lax
225
- parent ? parent.type_schema.schema(schema.to_a) : schema
268
+ our_schema = type_registry['hash'].schema(types).lax
269
+ schemas = [*parents.map(&:type_schema), our_schema]
270
+ schemas.inject { |result, schema| result.schema(schema.to_a) }
226
271
  end
227
272
 
228
273
  # Return a new DSL instance using the same processor type
@@ -276,14 +321,18 @@ module Dry
276
321
  #
277
322
  # @api private
278
323
  def filter_schema_dsl
279
- @filter_schema_dsl ||= new(parent: parent_filter_schema)
324
+ @filter_schema_dsl ||= new(parent: parent_filter_schemas)
280
325
  end
281
326
 
282
327
  # Check if any filter rules were defined
283
328
  #
284
329
  # @api private
285
330
  def filter_rules?
286
- (instance_variable_defined?('@filter_schema_dsl') && !filter_schema_dsl.macros.empty?) || parent&.filter_rules?
331
+ if instance_variable_defined?('@filter_schema_dsl') && !filter_schema_dsl.macros.empty?
332
+ return true
333
+ end
334
+
335
+ parents.any?(&:filter_rules?)
287
336
  end
288
337
 
289
338
  protected
@@ -323,10 +372,8 @@ module Dry
323
372
  private
324
373
 
325
374
  # @api private
326
- def parent_filter_schema
327
- return unless parent
328
-
329
- parent.filter_schema if parent.filter_rules?
375
+ def parent_filter_schemas
376
+ parents.select(&:filter_rules?).map(&:filter_schema)
330
377
  end
331
378
 
332
379
  # Build a key coercer
@@ -380,12 +427,12 @@ module Dry
380
427
 
381
428
  # @api private
382
429
  def parent_rules
383
- parent&.rules || EMPTY_HASH
430
+ parents.reduce({}) { |rules, parent| rules.merge(parent.rules) }
384
431
  end
385
432
 
386
433
  # @api private
387
434
  def parent_key_map
388
- parent&.key_map || EMPTY_ARRAY
435
+ parents.reduce([]) { |key_map, parent| parent.key_map + key_map }
389
436
  end
390
437
  end
391
438
  end
@@ -1,6 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'dry/logic/operators'
4
+ require 'dry/types/predicate_inferrer'
5
+ require 'dry/types/primitive_inferrer'
4
6
 
5
7
  require 'dry/schema/macros/core'
6
8
 
@@ -26,13 +28,13 @@ module Dry
26
28
  # PredicateInferrer is used to infer predicate type-check from a type spec
27
29
  # @return [PredicateInferrer]
28
30
  # @api private
29
- option :predicate_inferrer, default: proc { PredicateInferrer.new(compiler.predicates) }
31
+ option :predicate_inferrer, default: proc { ::Dry::Types::PredicateInferrer.new(compiler.predicates) }
30
32
 
31
33
  # @!attribute [r] primitive_inferrer
32
34
  # PrimitiveInferrer used to get a list of primitive classes from configured type
33
35
  # @return [PrimitiveInferrer]
34
36
  # @api private
35
- option :primitive_inferrer, default: proc { PrimitiveInferrer.new }
37
+ option :primitive_inferrer, default: proc { ::Dry::Types::PrimitiveInferrer.new }
36
38
 
37
39
  # @overload value(*predicates, **predicate_opts)
38
40
  # Set predicates without and with arguments
@@ -198,9 +200,7 @@ module Dry
198
200
  predicates = Array(type_spec ? args[1..-1] : args)
199
201
 
200
202
  if type_spec
201
- resolved_type = schema_dsl.resolve_type(
202
- nullable && !type_spec.is_a?(::Array) ? [:nil, type_spec] : type_spec
203
- )
203
+ resolved_type = resolve_type(type_spec, nullable)
204
204
 
205
205
  type(resolved_type) if set_type
206
206
 
@@ -213,6 +213,17 @@ module Dry
213
213
 
214
214
  yield(*predicates, type_spec: type_spec)
215
215
  end
216
+
217
+ # @api private
218
+ def resolve_type(type_spec, nullable)
219
+ resolved = schema_dsl.resolve_type(type_spec)
220
+
221
+ if type_spec.is_a?(::Array) || !nullable || resolved.optional?
222
+ resolved
223
+ else
224
+ schema_dsl.resolve_type([:nil, resolved])
225
+ end
226
+ end
216
227
  end
217
228
  end
218
229
  end
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'dry/schema/primitive_inferrer'
4
3
  require 'dry/schema/macros/value'
5
4
 
6
5
  module Dry
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'dry/schema/predicate_inferrer'
4
3
  require 'dry/schema/processor'
5
4
  require 'dry/schema/macros/dsl'
6
5
  require 'dry/schema/constants'
@@ -130,7 +130,8 @@ module Dry
130
130
  path: path.last, **tokens, **lookup_options(arg_vals: arg_vals, input: input)
131
131
  ).to_h
132
132
 
133
- template, meta = messages[predicate, options] || raise(MissingMessageError, path)
133
+ template, meta = messages[predicate, options] ||
134
+ raise(MissingMessageError.new(path, messages.looked_up_paths(predicate, options)))
134
135
 
135
136
  text = message_text(template, tokens, options)
136
137
 
@@ -99,23 +99,27 @@ module Dry
99
99
  end
100
100
  alias_method :[], :call
101
101
 
102
+ # Retrieve an array of looked up paths
103
+ #
104
+ # @param [Symbol] predicate
105
+ # @param [Hash] options
106
+ #
107
+ # @return [String]
108
+ #
109
+ # @api public
110
+ def looked_up_paths(predicate, options)
111
+ tokens = lookup_tokens(predicate, options)
112
+ filled_lookup_paths(tokens)
113
+ end
114
+
102
115
  # Try to find a message for the given predicate and its options
103
116
  #
104
117
  # @api private
105
118
  #
106
119
  # rubocop:disable Metrics/AbcSize
107
120
  def lookup(predicate, options)
108
- tokens = options.merge(
109
- predicate: predicate,
110
- root: options[:not] ? "#{root}.not" : root,
111
- arg_type: config.arg_types[options[:arg_type]],
112
- val_type: config.val_types[options[:val_type]],
113
- message_type: options[:message_type] || :failure
114
- )
115
-
116
121
  opts = options.reject { |k, _| config.lookup_options.include?(k) }
117
-
118
- path = lookup_paths(tokens).detect { |key| key?(key, opts) }
122
+ path = lookup_paths(predicate, options).detect { |key| key?(key, opts) }
119
123
 
120
124
  return unless path
121
125
 
@@ -130,7 +134,13 @@ module Dry
130
134
  # rubocop:enable Metrics/AbcSize
131
135
 
132
136
  # @api private
133
- def lookup_paths(tokens)
137
+ def lookup_paths(predicate, options)
138
+ tokens = lookup_tokens(predicate, options)
139
+ filled_lookup_paths(tokens)
140
+ end
141
+
142
+ # @api private
143
+ def filled_lookup_paths(tokens)
134
144
  config.lookup_paths.map { |path| path % tokens }
135
145
  end
136
146
 
@@ -178,6 +188,17 @@ module Dry
178
188
 
179
189
  private
180
190
 
191
+ # @api private
192
+ def lookup_tokens(predicate, options)
193
+ options.merge(
194
+ predicate: predicate,
195
+ root: options[:not] ? "#{root}.not" : root,
196
+ arg_type: config.arg_types[options[:arg_type]],
197
+ val_type: config.val_types[options[:val_type]],
198
+ message_type: options[:message_type] || :failure
199
+ )
200
+ end
201
+
181
202
  # @api private
182
203
  def custom_top_namespace?(path)
183
204
  path.to_s == DEFAULT_MESSAGES_PATH.to_s && config.top_namespace != DEFAULT_MESSAGES_ROOT
@@ -55,7 +55,7 @@ module Dry
55
55
  end
56
56
 
57
57
  # @api private
58
- def lookup_paths(tokens)
58
+ def filled_lookup_paths(tokens)
59
59
  super(tokens.merge(root: "#{tokens[:root]}.#{namespace}")) + super
60
60
  end
61
61
 
@@ -68,6 +68,18 @@ module Dry
68
68
  @t = proc { |key, locale: default_locale| get("%<locale>s.#{key}", locale: locale) }
69
69
  end
70
70
 
71
+ # Get an array of looked up paths
72
+ #
73
+ # @param [Symbol] predicate
74
+ # @param [Hash] options
75
+ #
76
+ # @return [String]
77
+ #
78
+ # @api public
79
+ def looked_up_paths(predicate, options)
80
+ super.map { |path| path % { locale: options[:locale] || default_locale } }
81
+ end
82
+
71
83
  # Get a message for the given key and its options
72
84
  #
73
85
  # @param [Symbol] key
@@ -1,35 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'dry/logic/predicates'
4
+ require 'dry/types/predicate_registry'
4
5
 
5
6
  module Dry
6
7
  module Schema
7
8
  # A registry with predicate objects from `Dry::Logic::Predicates`
8
9
  #
9
10
  # @api private
10
- class PredicateRegistry
11
- # @api private
12
- attr_reader :predicates
13
-
14
- # @api private
15
- attr_reader :has_predicate
16
-
17
- # @api private
18
- def initialize(predicates = Dry::Logic::Predicates)
19
- @predicates = predicates
20
- @has_predicate = ::Kernel.instance_method(:respond_to?).bind(@predicates)
21
- end
22
-
23
- # @api private
24
- def [](name)
25
- predicates[name]
26
- end
27
-
28
- # @api private
29
- def key?(name)
30
- has_predicate.(name)
31
- end
32
-
11
+ class PredicateRegistry < Dry::Types::PredicateRegistry
33
12
  # @api private
34
13
  def arg_list(name, *values)
35
14
  predicate = self[name]
@@ -5,6 +5,7 @@ require 'dry/initializer'
5
5
 
6
6
  require 'dry/schema/type_registry'
7
7
  require 'dry/schema/type_container'
8
+ require 'dry/schema/processor_steps'
8
9
  require 'dry/schema/rule_applier'
9
10
  require 'dry/schema/key_coercer'
10
11
  require 'dry/schema/value_coercer'
@@ -12,14 +13,9 @@ require 'dry/schema/value_coercer'
12
13
  module Dry
13
14
  module Schema
14
15
  # Processes input data using objects configured within the DSL
16
+ # Processing is split into steps represented by `ProcessorSteps`.
15
17
  #
16
- # Processing is split into 4 main steps:
17
- #
18
- # 1. Prepare input hash using a key map
19
- # 2. Apply pre-coercion filtering rules (optional step, used only when `filter` was used)
20
- # 3. Apply value coercions based on type specifications
21
- # 4. Apply rules
22
- #
18
+ # @see ProcessorSteps
23
19
  # @see Params
24
20
  # @see JSON
25
21
  #
@@ -32,7 +28,7 @@ module Dry
32
28
  setting :type_registry_namespace, :strict
33
29
  setting :filter_empty_string, false
34
30
 
35
- option :steps, default: -> { EMPTY_ARRAY.dup }
31
+ option :steps, default: -> { ProcessorSteps.new }
36
32
 
37
33
  option :schema_dsl
38
34
 
@@ -77,16 +73,6 @@ module Dry
77
73
  end
78
74
  end
79
75
 
80
- # Append a step
81
- #
82
- # @return [Processor]
83
- #
84
- # @api private
85
- def <<(step)
86
- steps << step
87
- self
88
- end
89
-
90
76
  # Apply processing steps to the provided input
91
77
  #
92
78
  # @param [Hash] input
@@ -96,10 +82,7 @@ module Dry
96
82
  # @api public
97
83
  def call(input)
98
84
  Result.new(input, message_compiler: message_compiler) do |result|
99
- steps.each do |step|
100
- output = step.(result)
101
- result.replace(output) if output.is_a?(::Hash)
102
- end
85
+ steps.call(result)
103
86
  end
104
87
  end
105
88
  alias_method :[], :call
@@ -119,7 +102,7 @@ module Dry
119
102
  #
120
103
  # @api public
121
104
  def key_map
122
- @key_map ||= steps.detect { |s| s.is_a?(KeyCoercer) }.key_map
105
+ steps[:key_coercer].key_map
123
106
  end
124
107
 
125
108
  # Return string represntation
@@ -139,7 +122,7 @@ module Dry
139
122
  #
140
123
  # @api private
141
124
  def type_schema
142
- @type_schema ||= steps.detect { |s| s.is_a?(ValueCoercer) }.type_schema
125
+ steps[:value_coercer].type_schema
143
126
  end
144
127
 
145
128
  # Return the rules config
@@ -180,7 +163,7 @@ module Dry
180
163
  #
181
164
  # @api private
182
165
  def rule_applier
183
- @rule_applier ||= steps.last
166
+ steps[:rule_applier]
184
167
  end
185
168
  alias_method :to_rule, :rule_applier
186
169
 
@@ -0,0 +1,101 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'dry/initializer'
4
+
5
+ module Dry
6
+ module Schema
7
+ # Steps for the Dry::Schema::Processor
8
+ #
9
+ # There are 4 main steps:
10
+ #
11
+ # 1. `key_coercer` - Prepare input hash using a key map
12
+ # 2. `filter_schema` - Apply pre-coercion filtering rules
13
+ # (optional step, used only when `filter` was used)
14
+ # 3. `value_coercer` - Apply value coercions based on type specifications
15
+ # 4. `rule_applier` - Apply rules
16
+ #
17
+ # @see Processor
18
+ #
19
+ # @api public
20
+ class ProcessorSteps
21
+ extend Dry::Initializer
22
+
23
+ STEPS_IN_ORDER = %i[key_coercer filter_schema value_coercer rule_applier].freeze
24
+
25
+ option :steps, default: -> { EMPTY_HASH.dup }
26
+ option :before_steps, default: -> { EMPTY_HASH.dup }
27
+ option :after_steps, default: -> { EMPTY_HASH.dup }
28
+
29
+ def call(result)
30
+ STEPS_IN_ORDER.each do |name|
31
+ before_steps[name]&.each { |step| process_step(step, result) }
32
+ process_step(steps[name], result)
33
+ after_steps[name]&.each { |step| process_step(step, result) }
34
+ end
35
+ result
36
+ end
37
+
38
+ # Return step by name
39
+ #
40
+ # @param [Symbol] name The step name
41
+ #
42
+ # @api public
43
+ def [](name)
44
+ steps[name]
45
+ end
46
+
47
+ # Sets step by name
48
+ #
49
+ # @param [Symbol] name The step name
50
+ #
51
+ # @api public
52
+ def []=(name, value)
53
+ validate_step_name(name)
54
+ steps[name] = value
55
+ end
56
+
57
+ # Add passed block before mentioned step
58
+ #
59
+ # @param [Symbol] name The step name
60
+ #
61
+ # @return [ProcessorSteps]
62
+ #
63
+ # @api public
64
+ def after(name, &block)
65
+ validate_step_name(name)
66
+ after_steps[name] ||= EMPTY_ARRAY.dup
67
+ after_steps[name] << block.to_proc
68
+ self
69
+ end
70
+
71
+ # Add passed block before mentioned step
72
+ #
73
+ # @param [Symbol] name The step name
74
+ #
75
+ # @return [ProcessorSteps]
76
+ #
77
+ # @api public
78
+ def before(name, &block)
79
+ validate_step_name(name)
80
+ before_steps[name] ||= EMPTY_ARRAY.dup
81
+ before_steps[name] << block.to_proc
82
+ self
83
+ end
84
+
85
+ # @api private
86
+ def process_step(step, result)
87
+ return unless step
88
+
89
+ output = step.(result)
90
+ result.replace(output) if output.is_a?(::Hash)
91
+ end
92
+
93
+ # @api private
94
+ def validate_step_name(name)
95
+ return if STEPS_IN_ORDER.include?(name)
96
+
97
+ raise ArgumentError, "Undefined step name #{name}. Available names: #{STEPS_IN_ORDER}"
98
+ end
99
+ end
100
+ end
101
+ end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Dry
4
4
  module Schema
5
- VERSION = '1.3.4'
5
+ VERSION = '1.4.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.3.4
4
+ version: 1.4.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-09-11 00:00:00.000000000 Z
11
+ date: 2019-10-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby
@@ -106,14 +106,14 @@ dependencies:
106
106
  requirements:
107
107
  - - "~>"
108
108
  - !ruby/object:Gem::Version
109
- version: '1.0'
109
+ version: '1.2'
110
110
  type: :runtime
111
111
  prerelease: false
112
112
  version_requirements: !ruby/object:Gem::Requirement
113
113
  requirements:
114
114
  - - "~>"
115
115
  - !ruby/object:Gem::Version
116
- version: '1.0'
116
+ version: '1.2'
117
117
  - !ruby/object:Gem::Dependency
118
118
  name: bundler
119
119
  requirement: !ruby/object:Gem::Requirement
@@ -217,8 +217,8 @@ files:
217
217
  - lib/dry/schema/predicate.rb
218
218
  - lib/dry/schema/predicate_inferrer.rb
219
219
  - lib/dry/schema/predicate_registry.rb
220
- - lib/dry/schema/primitive_inferrer.rb
221
220
  - lib/dry/schema/processor.rb
221
+ - lib/dry/schema/processor_steps.rb
222
222
  - lib/dry/schema/result.rb
223
223
  - lib/dry/schema/rule_applier.rb
224
224
  - lib/dry/schema/trace.rb
@@ -1,99 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'dry/core/cache'
4
-
5
- module Dry
6
- module Schema
7
- # PrimitiveInferrer is used internally by `Macros::Filled`
8
- # for inferring a list of possible primitives that a given
9
- # type can handle.
10
- #
11
- # @api private
12
- class PrimitiveInferrer
13
- extend Dry::Core::Cache
14
-
15
- # Compiler reduces type AST into a list of primitives
16
- #
17
- # @api private
18
- class Compiler
19
- # @api private
20
- def visit(node)
21
- meth, rest = node
22
- public_send(:"visit_#{meth}", rest)
23
- end
24
-
25
- # @api private
26
- def visit_nominal(node)
27
- type, _ = node
28
- type
29
- end
30
-
31
- # @api private
32
- def visit_hash(_)
33
- Hash
34
- end
35
- alias_method :visit_schema, :visit_hash
36
-
37
- # @api private
38
- def visit_array(_)
39
- Array
40
- end
41
-
42
- # @api private
43
- def visit_lax(node)
44
- visit(node)
45
- end
46
-
47
- # @api private
48
- def visit_constructor(node)
49
- other, * = node
50
- visit(other)
51
- end
52
-
53
- # @api private
54
- def visit_enum(node)
55
- other, * = node
56
- visit(other)
57
- end
58
-
59
- # @api private
60
- def visit_sum(node)
61
- left, right = node
62
-
63
- [visit(left), visit(right)].flatten(1)
64
- end
65
-
66
- # @api private
67
- def visit_constrained(node)
68
- other, * = node
69
- visit(other)
70
- end
71
-
72
- # @api private
73
- def visit_any(_)
74
- Object
75
- end
76
- end
77
-
78
- # @return [Compiler]
79
- # @api private
80
- attr_reader :compiler
81
-
82
- # @api private
83
- def initialize
84
- @compiler = Compiler.new
85
- end
86
-
87
- # Infer predicate identifier from the provided type
88
- #
89
- # @return [Symbol]
90
- #
91
- # @api private
92
- def [](type)
93
- self.class.fetch_or_store(type.hash) do
94
- Array(compiler.visit(type.to_ast)).freeze
95
- end
96
- end
97
- end
98
- end
99
- end