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

mensfeld