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