dry-schema 1.0.3 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +18 -0
- data/lib/dry/schema/config.rb +31 -14
- data/lib/dry/schema/dsl.rb +43 -23
- data/lib/dry/schema/json.rb +1 -0
- data/lib/dry/schema/macros/dsl.rb +3 -2
- data/lib/dry/schema/macros/filled.rb +43 -5
- data/lib/dry/schema/macros/key.rb +6 -5
- data/lib/dry/schema/macros/value.rb +3 -0
- data/lib/dry/schema/messages/abstract.rb +2 -1
- data/lib/dry/schema/messages/i18n.rb +1 -1
- data/lib/dry/schema/messages/yaml.rb +2 -0
- data/lib/dry/schema/params.rb +1 -0
- data/lib/dry/schema/primitive_inferrer.rb +98 -0
- data/lib/dry/schema/processor.rb +23 -4
- data/lib/dry/schema/value_coercer.rb +3 -0
- data/lib/dry/schema/version.rb +1 -1
- metadata +9 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5a4bd19052082cf526e57fca967abe2bbfbdcdfd4c1439c09acfb19bc3b25562
|
4
|
+
data.tar.gz: 82ffd3bf33409876cf372406e480ca25de8776dfad334ff634b0b041f2ca33ed
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dfde0da5889a34f7ef68699048cd755462f49d9d6249435fd5e0006a8d482dfa3a130e73397f02a83bbb11a4ad2c6e5c039e53154a0072d7f89e4a71ee89748b
|
7
|
+
data.tar.gz: dbc0e2f57947b69241c34451980af16b2c60be5cffb770c510f9ddce91daf58a9e6d900eac2884ca88f30c88dce415a4d6bd629d97922a3c79458458fd3ec289
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,21 @@
|
|
1
|
+
# v1.1.0 2019-05-30
|
2
|
+
|
3
|
+
### Added
|
4
|
+
|
5
|
+
* `Config` exposes `predicates` setting too (solnic)
|
6
|
+
|
7
|
+
### Fixed
|
8
|
+
|
9
|
+
* `filled` macro behavior results in `must be filled` error messages when appropriate - see PR #141 for more information (issue #134) (solnic)
|
10
|
+
* Filter rules no longer cause keys to be added to input (issue #142) (solnic)
|
11
|
+
* Filter rules work now with inheritance (solnic)
|
12
|
+
* Inherited type schemas used by coercion are now properly configured as `lax` type (solnic)
|
13
|
+
* `Config` is now finalized before instantiating schemas and properly dupped when its inherited (flash-gordon + solnic)
|
14
|
+
* `Config#eql?` works as expected (solnic)
|
15
|
+
* Predicates are properly inferred from array with a member type spec, ie `array[:integer]` results in `array? + each(:integer?)` (issue #140) (solnic)
|
16
|
+
|
17
|
+
[Compare v1.0.3...v1.1.0](https://github.com/dry-rb/dry-schema/compare/v1.0.3...v1.1.0)
|
18
|
+
|
1
19
|
# v1.0.3 2019-05-21
|
2
20
|
|
3
21
|
### Fixed
|
data/lib/dry/schema/config.rb
CHANGED
@@ -15,33 +15,50 @@ module Dry
|
|
15
15
|
# @api public
|
16
16
|
class Config
|
17
17
|
include Dry::Configurable
|
18
|
-
include Dry::Equalizer(:
|
18
|
+
include Dry::Equalizer(:to_h, inspect: false)
|
19
19
|
|
20
|
+
# @!method predicates
|
21
|
+
#
|
22
|
+
# Return configured predicate registry
|
23
|
+
#
|
24
|
+
# @return [Schema::PredicateRegistry]
|
25
|
+
#
|
26
|
+
# @api public
|
20
27
|
setting(:predicates, Schema::PredicateRegistry.new)
|
21
28
|
|
29
|
+
# @!method messages
|
30
|
+
#
|
31
|
+
# Return configuration for message backend
|
32
|
+
#
|
33
|
+
# @return [Dry::Configurable::Config]
|
34
|
+
#
|
35
|
+
# @api public
|
22
36
|
setting(:messages) do
|
23
37
|
setting(:backend, :yaml)
|
24
38
|
setting(:namespace)
|
25
39
|
setting(:load_paths, Set[DEFAULT_MESSAGES_PATH], &:dup)
|
26
40
|
setting(:top_namespace, DEFAULT_MESSAGES_ROOT)
|
41
|
+
setting(:default_locale, nil)
|
27
42
|
end
|
28
43
|
|
29
|
-
#
|
30
|
-
|
31
|
-
|
32
|
-
#
|
33
|
-
# @api public
|
34
|
-
def predicates
|
35
|
-
config.predicates
|
44
|
+
# @api private
|
45
|
+
def respond_to_missing?(meth, include_private = false)
|
46
|
+
super || config.respond_to?(meth, include_private)
|
36
47
|
end
|
37
48
|
|
38
|
-
#
|
39
|
-
|
40
|
-
|
49
|
+
# @api private
|
50
|
+
def inspect
|
51
|
+
"#<#{self.class} #{to_h.map { |k,v| ["#{k}=", v.inspect] }.map(&:join).join(' ')}>"
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
# Forward to the underlying config object
|
41
57
|
#
|
42
|
-
# @api
|
43
|
-
def
|
44
|
-
config.
|
58
|
+
# @api private
|
59
|
+
def method_missing(meth, *args, &block)
|
60
|
+
super unless config.respond_to?(meth)
|
61
|
+
config.public_send(meth, *args)
|
45
62
|
end
|
46
63
|
end
|
47
64
|
end
|
data/lib/dry/schema/dsl.rb
CHANGED
@@ -111,6 +111,17 @@ module Dry
|
|
111
111
|
self
|
112
112
|
end
|
113
113
|
|
114
|
+
# Return a macro with the provided name
|
115
|
+
#
|
116
|
+
# @param [Symbol] name
|
117
|
+
#
|
118
|
+
# @return [Macros::Core]
|
119
|
+
#
|
120
|
+
# @api public
|
121
|
+
def [](name)
|
122
|
+
macros.detect { |macro| macro.name.equal?(name) }
|
123
|
+
end
|
124
|
+
|
114
125
|
# Define a required key
|
115
126
|
#
|
116
127
|
# @example
|
@@ -164,7 +175,7 @@ module Dry
|
|
164
175
|
name: name,
|
165
176
|
compiler: compiler,
|
166
177
|
schema_dsl: self,
|
167
|
-
|
178
|
+
filter_schema_dsl: filter_schema_dsl
|
168
179
|
)
|
169
180
|
|
170
181
|
macro.value(&block) if block
|
@@ -174,7 +185,7 @@ module Dry
|
|
174
185
|
|
175
186
|
# Build a processor based on DSL's definitions
|
176
187
|
#
|
177
|
-
# @return [Processor]
|
188
|
+
# @return [Processor, Params, JSON]
|
178
189
|
#
|
179
190
|
# @api private
|
180
191
|
def call
|
@@ -182,7 +193,7 @@ module Dry
|
|
182
193
|
steps << filter_schema.rule_applier if filter_rules?
|
183
194
|
steps << value_coercer << rule_applier
|
184
195
|
|
185
|
-
processor_type.new
|
196
|
+
processor_type.new(schema_dsl: self, steps: steps)
|
186
197
|
end
|
187
198
|
|
188
199
|
# Cast this DSL into a rule object
|
@@ -210,11 +221,8 @@ module Dry
|
|
210
221
|
#
|
211
222
|
# @api private
|
212
223
|
def type_schema
|
213
|
-
|
214
|
-
|
215
|
-
else
|
216
|
-
type_registry['hash'].schema(types).lax
|
217
|
-
end
|
224
|
+
schema = type_registry['hash'].schema(types).lax
|
225
|
+
parent ? parent.type_schema.schema(schema.to_a) : schema
|
218
226
|
end
|
219
227
|
|
220
228
|
# Return a new DSL instance using the same processor type
|
@@ -222,8 +230,8 @@ module Dry
|
|
222
230
|
# @return [Dry::Types::Safe]
|
223
231
|
#
|
224
232
|
# @api private
|
225
|
-
def new(&block)
|
226
|
-
self.class.new(processor_type: processor_type, &block)
|
233
|
+
def new(options = EMPTY_HASH, &block)
|
234
|
+
self.class.new(options.merge(processor_type: processor_type), &block)
|
227
235
|
end
|
228
236
|
|
229
237
|
# Set a type for the given key name
|
@@ -257,6 +265,27 @@ module Dry
|
|
257
265
|
end
|
258
266
|
end
|
259
267
|
|
268
|
+
# @api private
|
269
|
+
def filter_schema
|
270
|
+
filter_schema_dsl.call
|
271
|
+
end
|
272
|
+
|
273
|
+
# Build an input schema DSL used by `filter` API
|
274
|
+
#
|
275
|
+
# @see Macros::Value#filter
|
276
|
+
#
|
277
|
+
# @api private
|
278
|
+
def filter_schema_dsl
|
279
|
+
@filter_schema_dsl ||= new(parent: parent_filter_schema)
|
280
|
+
end
|
281
|
+
|
282
|
+
# Check if any filter rules were defined
|
283
|
+
#
|
284
|
+
# @api private
|
285
|
+
def filter_rules?
|
286
|
+
(instance_variable_defined?('@filter_schema_dsl') && !filter_schema_dsl.macros.empty?) || parent&.filter_rules?
|
287
|
+
end
|
288
|
+
|
260
289
|
protected
|
261
290
|
|
262
291
|
# Build a rule applier
|
@@ -265,7 +294,7 @@ module Dry
|
|
265
294
|
#
|
266
295
|
# @api protected
|
267
296
|
def rule_applier
|
268
|
-
RuleApplier.new(rules, config: config)
|
297
|
+
RuleApplier.new(rules, config: config.finalize!)
|
269
298
|
end
|
270
299
|
|
271
300
|
# Build rules from defined macros
|
@@ -293,20 +322,11 @@ module Dry
|
|
293
322
|
|
294
323
|
private
|
295
324
|
|
296
|
-
# Check if any filter rules were defined
|
297
|
-
#
|
298
325
|
# @api private
|
299
|
-
def
|
300
|
-
|
301
|
-
end
|
326
|
+
def parent_filter_schema
|
327
|
+
return unless parent
|
302
328
|
|
303
|
-
|
304
|
-
#
|
305
|
-
# @see Macros::Value#filter
|
306
|
-
#
|
307
|
-
# @api private
|
308
|
-
def filter_schema
|
309
|
-
@__filter_schema__ ||= new
|
329
|
+
parent.filter_schema if parent.filter_rules?
|
310
330
|
end
|
311
331
|
|
312
332
|
# Build a key coercer
|
data/lib/dry/schema/json.rb
CHANGED
@@ -66,9 +66,10 @@ module Dry
|
|
66
66
|
# @return [Macros::Core]
|
67
67
|
#
|
68
68
|
# @api public
|
69
|
-
def filled(*args, &block)
|
69
|
+
def filled(*args, **opts, &block)
|
70
70
|
append_macro(Macros::Filled) do |macro|
|
71
|
-
macro.
|
71
|
+
filter(:filled?) if opts[:type_spec] && macro.filter?
|
72
|
+
macro.call(*args, **opts, &block)
|
72
73
|
end
|
73
74
|
end
|
74
75
|
|
@@ -1,5 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'dry/schema/primitive_inferrer'
|
3
4
|
require 'dry/schema/macros/value'
|
4
5
|
|
5
6
|
module Dry
|
@@ -9,8 +10,30 @@ module Dry
|
|
9
10
|
#
|
10
11
|
# @api private
|
11
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
|
+
|
12
19
|
# @api private
|
13
20
|
def call(*predicates, **opts, &block)
|
21
|
+
ensure_valid_predicates(predicates)
|
22
|
+
|
23
|
+
if opts[:type_spec]
|
24
|
+
if filter?
|
25
|
+
value(*predicates, **opts, &block)
|
26
|
+
else
|
27
|
+
value(predicates[0], :filled?, *predicates[1..predicates.size - 1], **opts, &block)
|
28
|
+
end
|
29
|
+
else
|
30
|
+
value(:filled?, *predicates, **opts, &block)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# @api private
|
35
|
+
# rubocop:disable Style/GuardClause
|
36
|
+
def ensure_valid_predicates(predicates)
|
14
37
|
if predicates.include?(:empty?)
|
15
38
|
raise ::Dry::Schema::InvalidSchemaError, 'Using filled with empty? predicate is invalid'
|
16
39
|
end
|
@@ -18,12 +41,27 @@ module Dry
|
|
18
41
|
if predicates.include?(:filled?)
|
19
42
|
raise ::Dry::Schema::InvalidSchemaError, 'Using filled with filled? is redundant'
|
20
43
|
end
|
44
|
+
end
|
45
|
+
# rubocop:enable Style/GuardClause
|
21
46
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
47
|
+
# @api private
|
48
|
+
def filter?
|
49
|
+
!primitives.include?(NilClass) && processor_config.filter_empty_string
|
50
|
+
end
|
51
|
+
|
52
|
+
# @api private
|
53
|
+
def processor_config
|
54
|
+
schema_dsl.processor_type.config
|
55
|
+
end
|
56
|
+
|
57
|
+
# @api private
|
58
|
+
def primitives
|
59
|
+
primitive_inferrer[schema_type]
|
60
|
+
end
|
61
|
+
|
62
|
+
# @api private
|
63
|
+
def schema_type
|
64
|
+
schema_dsl.types[name]
|
27
65
|
end
|
28
66
|
end
|
29
67
|
end
|
@@ -12,9 +12,10 @@ module Dry
|
|
12
12
|
#
|
13
13
|
# @api public
|
14
14
|
class Key < DSL
|
15
|
-
#
|
16
|
-
#
|
17
|
-
|
15
|
+
# @!attribute [r] filter_schema_dsl
|
16
|
+
# @return [Schema::DSL]
|
17
|
+
# @api private
|
18
|
+
option :filter_schema_dsl, default: proc { schema_dsl&.filter_schema_dsl }
|
18
19
|
|
19
20
|
# Specify predicates that should be applied before coercion
|
20
21
|
#
|
@@ -27,7 +28,7 @@ module Dry
|
|
27
28
|
#
|
28
29
|
# @api public
|
29
30
|
def filter(*args, &block)
|
30
|
-
|
31
|
+
(filter_schema_dsl[name] || filter_schema_dsl.optional(name)).value(*args, &block)
|
31
32
|
self
|
32
33
|
end
|
33
34
|
|
@@ -54,7 +55,7 @@ module Dry
|
|
54
55
|
# @api public
|
55
56
|
def value(*args, **opts, &block)
|
56
57
|
extract_type_spec(*args) do |*predicates, type_spec:|
|
57
|
-
super(*predicates, **opts, &block)
|
58
|
+
super(*predicates, type_spec: type_spec, **opts, &block)
|
58
59
|
end
|
59
60
|
end
|
60
61
|
|
@@ -18,6 +18,7 @@ module Dry
|
|
18
18
|
include Dry::Configurable
|
19
19
|
include Dry::Equalizer(:config)
|
20
20
|
|
21
|
+
setting :default_locale, nil
|
21
22
|
setting :load_paths, Set[DEFAULT_MESSAGES_PATH]
|
22
23
|
setting :top_namespace, DEFAULT_MESSAGES_ROOT
|
23
24
|
setting :root, 'errors'
|
@@ -163,7 +164,7 @@ module Dry
|
|
163
164
|
|
164
165
|
# @api private
|
165
166
|
def default_locale
|
166
|
-
|
167
|
+
config.default_locale
|
167
168
|
end
|
168
169
|
|
169
170
|
private
|
@@ -30,6 +30,8 @@ module Dry
|
|
30
30
|
# @api private
|
31
31
|
def self.build(options = EMPTY_HASH)
|
32
32
|
super do |config|
|
33
|
+
config.default_locale = :en unless config.default_locale
|
34
|
+
|
33
35
|
config.root = "%<locale>s.#{config.root}"
|
34
36
|
|
35
37
|
config.rule_lookup_paths = config.rule_lookup_paths.map { |path|
|
data/lib/dry/schema/params.rb
CHANGED
@@ -0,0 +1,98 @@
|
|
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
|
+
|
36
|
+
# @api private
|
37
|
+
def visit_array(_)
|
38
|
+
Array
|
39
|
+
end
|
40
|
+
|
41
|
+
# @api private
|
42
|
+
def visit_lax(node)
|
43
|
+
visit(node)
|
44
|
+
end
|
45
|
+
|
46
|
+
# @api private
|
47
|
+
def visit_constructor(node)
|
48
|
+
other, * = node
|
49
|
+
visit(other)
|
50
|
+
end
|
51
|
+
|
52
|
+
# @api private
|
53
|
+
def visit_enum(node)
|
54
|
+
other, * = node
|
55
|
+
visit(other)
|
56
|
+
end
|
57
|
+
|
58
|
+
# @api private
|
59
|
+
def visit_sum(node)
|
60
|
+
left, right = node
|
61
|
+
|
62
|
+
[visit(left), visit(right)].flatten(1)
|
63
|
+
end
|
64
|
+
|
65
|
+
# @api private
|
66
|
+
def visit_constrained(node)
|
67
|
+
other, * = node
|
68
|
+
visit(other)
|
69
|
+
end
|
70
|
+
|
71
|
+
# @api private
|
72
|
+
def visit_any(_)
|
73
|
+
Object
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
# @return [Compiler]
|
78
|
+
# @api private
|
79
|
+
attr_reader :compiler
|
80
|
+
|
81
|
+
# @api private
|
82
|
+
def initialize
|
83
|
+
@compiler = Compiler.new
|
84
|
+
end
|
85
|
+
|
86
|
+
# Infer predicate identifier from the provided type
|
87
|
+
#
|
88
|
+
# @return [Symbol]
|
89
|
+
#
|
90
|
+
# @api private
|
91
|
+
def [](type)
|
92
|
+
self.class.fetch_or_store(type.hash) do
|
93
|
+
Array(compiler.visit(type.to_ast)).freeze
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
data/lib/dry/schema/processor.rb
CHANGED
@@ -29,8 +29,11 @@ module Dry
|
|
29
29
|
|
30
30
|
setting :key_map_type
|
31
31
|
setting :type_registry, TypeRegistry.new
|
32
|
+
setting :filter_empty_string, false
|
32
33
|
|
33
|
-
|
34
|
+
option :steps, default: -> { EMPTY_ARRAY.dup }
|
35
|
+
|
36
|
+
option :schema_dsl
|
34
37
|
|
35
38
|
class << self
|
36
39
|
# Return DSL configured via #define
|
@@ -60,9 +63,11 @@ module Dry
|
|
60
63
|
# @return [Processor]
|
61
64
|
#
|
62
65
|
# @api public
|
63
|
-
def new(&block)
|
64
|
-
if block
|
65
|
-
super
|
66
|
+
def new(options = nil, &block)
|
67
|
+
if options || block
|
68
|
+
processor = super
|
69
|
+
yield(processor) if block
|
70
|
+
processor
|
66
71
|
elsif definition
|
67
72
|
definition.call
|
68
73
|
else
|
@@ -177,6 +182,20 @@ module Dry
|
|
177
182
|
@rule_applier ||= steps.last
|
178
183
|
end
|
179
184
|
alias_method :to_rule, :rule_applier
|
185
|
+
|
186
|
+
# Check if there are filter rules
|
187
|
+
#
|
188
|
+
# @api private
|
189
|
+
def filter_rules?
|
190
|
+
@filter_rules_predicate ||= schema_dsl.filter_rules?
|
191
|
+
end
|
192
|
+
|
193
|
+
# Return filter schema
|
194
|
+
#
|
195
|
+
# @api private
|
196
|
+
def filter_schema
|
197
|
+
@filter_schema ||= schema_dsl.filter_schema
|
198
|
+
end
|
180
199
|
end
|
181
200
|
end
|
182
201
|
end
|
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.0
|
4
|
+
version: 1.1.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-05-
|
11
|
+
date: 2019-05-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: concurrent-ruby
|
@@ -28,22 +28,22 @@ dependencies:
|
|
28
28
|
name: dry-configurable
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - ">="
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: 0.8.0
|
34
31
|
- - "~>"
|
35
32
|
- !ruby/object:Gem::Version
|
36
33
|
version: '0.8'
|
34
|
+
- - ">="
|
35
|
+
- !ruby/object:Gem::Version
|
36
|
+
version: 0.8.3
|
37
37
|
type: :runtime
|
38
38
|
prerelease: false
|
39
39
|
version_requirements: !ruby/object:Gem::Requirement
|
40
40
|
requirements:
|
41
|
-
- - ">="
|
42
|
-
- !ruby/object:Gem::Version
|
43
|
-
version: 0.8.0
|
44
41
|
- - "~>"
|
45
42
|
- !ruby/object:Gem::Version
|
46
43
|
version: '0.8'
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: 0.8.3
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: dry-core
|
49
49
|
requirement: !ruby/object:Gem::Requirement
|
@@ -217,6 +217,7 @@ 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
|
220
221
|
- lib/dry/schema/processor.rb
|
221
222
|
- lib/dry/schema/result.rb
|
222
223
|
- lib/dry/schema/rule_applier.rb
|