dry-schema 0.2.0 → 0.3.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 +17 -0
- data/LICENSE +1 -1
- data/README.md +11 -2
- data/lib/dry-schema.rb +2 -0
- data/lib/dry/schema.rb +2 -0
- data/lib/dry/schema/compiler.rb +2 -0
- data/lib/dry/schema/config.rb +2 -0
- data/lib/dry/schema/constants.rb +4 -2
- data/lib/dry/schema/dsl.rb +5 -3
- data/lib/dry/schema/extensions.rb +2 -0
- data/lib/dry/schema/extensions/hints.rb +2 -0
- data/lib/dry/schema/extensions/hints/message_compiler_methods.rb +10 -3
- data/lib/dry/schema/extensions/hints/message_set_methods.rb +3 -1
- data/lib/dry/schema/extensions/hints/result_methods.rb +2 -0
- data/lib/dry/schema/extensions/monads.rb +3 -2
- data/lib/dry/schema/json.rb +3 -1
- data/lib/dry/schema/key.rb +3 -1
- data/lib/dry/schema/key_coercer.rb +2 -0
- data/lib/dry/schema/key_map.rb +3 -1
- data/lib/dry/schema/macros.rb +3 -0
- data/lib/dry/schema/macros/array.rb +27 -0
- data/lib/dry/schema/macros/core.rb +2 -0
- data/lib/dry/schema/macros/dsl.rb +3 -2
- data/lib/dry/schema/macros/each.rb +2 -0
- data/lib/dry/schema/macros/filled.rb +4 -2
- data/lib/dry/schema/macros/hash.rb +2 -0
- data/lib/dry/schema/macros/key.rb +7 -3
- data/lib/dry/schema/macros/maybe.rb +4 -2
- data/lib/dry/schema/macros/optional.rb +2 -0
- data/lib/dry/schema/macros/required.rb +2 -0
- data/lib/dry/schema/macros/schema.rb +2 -0
- data/lib/dry/schema/macros/value.rb +10 -3
- data/lib/dry/schema/message.rb +14 -0
- data/lib/dry/schema/message_compiler.rb +4 -2
- data/lib/dry/schema/message_compiler/visitor_opts.rb +2 -0
- data/lib/dry/schema/message_set.rb +2 -0
- data/lib/dry/schema/messages.rb +2 -0
- data/lib/dry/schema/messages/abstract.rb +5 -3
- data/lib/dry/schema/messages/i18n.rb +3 -1
- data/lib/dry/schema/messages/namespaced.rb +3 -1
- data/lib/dry/schema/messages/template.rb +3 -1
- data/lib/dry/schema/messages/yaml.rb +7 -3
- data/lib/dry/schema/namespaced_rule.rb +2 -0
- data/lib/dry/schema/params.rb +3 -1
- data/lib/dry/schema/path.rb +21 -2
- data/lib/dry/schema/predicate.rb +2 -0
- data/lib/dry/schema/predicate_inferrer.rb +69 -20
- data/lib/dry/schema/predicate_registry.rb +2 -0
- data/lib/dry/schema/processor.rb +11 -0
- data/lib/dry/schema/result.rb +3 -1
- data/lib/dry/schema/rule_applier.rb +2 -0
- data/lib/dry/schema/trace.rb +2 -0
- data/lib/dry/schema/type_registry.rb +3 -1
- data/lib/dry/schema/types.rb +2 -0
- data/lib/dry/schema/value_coercer.rb +2 -0
- data/lib/dry/schema/version.rb +3 -1
- metadata +24 -23
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 149b82a73e8cd4d31c55fe1cf2bee1a7ebfb2afd696677522293da435f0224b1
|
4
|
+
data.tar.gz: ca76ca603a34906e61cfbd075e9667c97ee191591520e89b8a5d2e949c124426
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0b94f326035f884457e2b6ce84ed427d2ec31011529cb8c4a987ff8c26a1bf4b66581ccd1e14ebe91cd4a0efbd05c9c04be6c47cfe959fa0f08687515f02d364
|
7
|
+
data.tar.gz: 356ae43e85fc3afdc0e8abd2628c06315ce5ed97d3ec74c40a3a32dd73b1300851c0f1f8c674abb73d3d8723292dfe0bf370ec5f5fcf1fd7f21fc5a8eb16633c
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,20 @@
|
|
1
|
+
# 0.3.0 2018-03-04
|
2
|
+
|
3
|
+
### Fixed
|
4
|
+
|
5
|
+
* Configuration is properly inherited from a parent schema (skryukov)
|
6
|
+
* `Result#error?` returns `true` when a preceding key has errors (solnic)
|
7
|
+
* Predicate inferrer no longer chokes on sum, constructor and enum types (solnic)
|
8
|
+
* Predicate inferrer infers `:bool?` from boolean types (solnic)
|
9
|
+
* Block-based definitions using `array` works correctly (solnic)
|
10
|
+
* Using a disjunction with `array` and `hash` produces correct errors when element validation for array failed (solnic)
|
11
|
+
|
12
|
+
### Changed
|
13
|
+
|
14
|
+
* Required ruby version was removed from gemspec for people who are stuck on MRI 2.3.x (solnic)
|
15
|
+
|
16
|
+
[Compare v0.2.0...v0.3.0](https://github.com/dry-rb/dry-schema/compare/v0.2.0...v0.3.0)
|
17
|
+
|
1
18
|
# 0.2.0 2019-02-26
|
2
19
|
|
3
20
|
### Added
|
data/LICENSE
CHANGED
data/README.md
CHANGED
@@ -12,9 +12,18 @@
|
|
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]
|
14
14
|
|
15
|
-
|
15
|
+
## Links
|
16
16
|
|
17
|
-
* [Documentation](http://dry-rb.org/gems/dry-schema)
|
17
|
+
* [Documentation](http://dry-rb.org/gems/dry-schema)
|
18
|
+
|
19
|
+
## Supported Ruby versions
|
20
|
+
|
21
|
+
This library officially supports following Ruby versions:
|
22
|
+
|
23
|
+
* MRI >= `2.4`
|
24
|
+
* jruby >= `9.2`
|
25
|
+
|
26
|
+
It **should** work on MRI `2.3.x` too, but there's no official support for this version.
|
18
27
|
|
19
28
|
## License
|
20
29
|
|
data/lib/dry-schema.rb
CHANGED
data/lib/dry/schema.rb
CHANGED
data/lib/dry/schema/compiler.rb
CHANGED
data/lib/dry/schema/config.rb
CHANGED
data/lib/dry/schema/constants.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'dry/core/constants'
|
2
4
|
|
3
5
|
module Dry
|
@@ -7,7 +9,7 @@ module Dry
|
|
7
9
|
InvalidSchemaError = Class.new(StandardError)
|
8
10
|
MissingMessageError = Class.new(StandardError)
|
9
11
|
|
10
|
-
QUESTION_MARK = '?'
|
11
|
-
DOT = '.'
|
12
|
+
QUESTION_MARK = '?'
|
13
|
+
DOT = '.'
|
12
14
|
end
|
13
15
|
end
|
data/lib/dry/schema/dsl.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'dry/initializer'
|
2
4
|
|
3
5
|
require 'dry/schema/constants'
|
@@ -72,7 +74,7 @@ module Dry
|
|
72
74
|
|
73
75
|
# @!attribute [r] config
|
74
76
|
# @return [Config] Configuration object exposed via `#configure` method
|
75
|
-
option :config, optional: true, default:
|
77
|
+
option :config, optional: true, default: proc { parent ? parent.config.dup : Config.new }
|
76
78
|
|
77
79
|
# Build a new DSL object and evaluate provided block
|
78
80
|
#
|
@@ -203,7 +205,7 @@ module Dry
|
|
203
205
|
#
|
204
206
|
# @api public
|
205
207
|
def array
|
206
|
-
-> member_type { type_registry[
|
208
|
+
-> member_type { type_registry['array'].of(resolve_type(member_type)) }
|
207
209
|
end
|
208
210
|
|
209
211
|
# Return type schema used by the value coercer
|
@@ -212,7 +214,7 @@ module Dry
|
|
212
214
|
#
|
213
215
|
# @api private
|
214
216
|
def type_schema
|
215
|
-
type_registry[
|
217
|
+
type_registry['hash'].schema(types.merge(parent_types)).safe
|
216
218
|
end
|
217
219
|
|
218
220
|
# Return a new DSL instance using the same processor type
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Dry
|
2
4
|
module Schema
|
3
5
|
module Extensions
|
@@ -30,14 +32,19 @@ module Dry
|
|
30
32
|
# @api private
|
31
33
|
def exclude?(messages, opts)
|
32
34
|
Array(messages).all? do |msg|
|
33
|
-
hints = opts
|
35
|
+
hints = opts
|
36
|
+
.hints
|
37
|
+
.reject { |hint| msg == hint }
|
38
|
+
.reject { |hint| hint.predicate == :filled? }
|
39
|
+
|
34
40
|
key_failure = opts.key_failure?(msg.path)
|
35
41
|
predicate = msg.predicate
|
36
42
|
|
37
43
|
(HINT_TYPE_EXCLUSION.include?(predicate) && !key_failure) ||
|
38
44
|
(msg.predicate == :filled? && key_failure) ||
|
39
|
-
|
40
|
-
|
45
|
+
(!key_failure && HINT_TYPE_EXCLUSION.include?(predicate) &&
|
46
|
+
!hints.empty? && hints.any? { |hint| hint.path == msg.path }) ||
|
47
|
+
HINT_OTHER_EXCLUSION.include?(predicate)
|
41
48
|
end
|
42
49
|
end
|
43
50
|
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'dry/monads/result'
|
2
4
|
|
3
5
|
module Dry
|
@@ -9,10 +11,9 @@ module Dry
|
|
9
11
|
if success?
|
10
12
|
Success(output)
|
11
13
|
else
|
12
|
-
Failure(
|
14
|
+
Failure(message_set(options).dump)
|
13
15
|
end
|
14
16
|
end
|
15
|
-
alias_method :to_result, :to_monad
|
16
17
|
end
|
17
18
|
end
|
18
19
|
end
|
data/lib/dry/schema/json.rb
CHANGED
data/lib/dry/schema/key.rb
CHANGED
data/lib/dry/schema/key_map.rb
CHANGED
data/lib/dry/schema/macros.rb
CHANGED
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'dry/schema/macros/dsl'
|
4
|
+
|
5
|
+
module Dry
|
6
|
+
module Schema
|
7
|
+
module Macros
|
8
|
+
# Macro used to specify predicates for each element of an array
|
9
|
+
#
|
10
|
+
# @api public
|
11
|
+
class Array < DSL
|
12
|
+
# @api private
|
13
|
+
def value(*args, &block)
|
14
|
+
schema_dsl.set_type(name, :array)
|
15
|
+
super
|
16
|
+
end
|
17
|
+
|
18
|
+
# @api private
|
19
|
+
def to_ast(*)
|
20
|
+
[:and, [trace.array?.to_ast, [:each, trace.to_ast]]]
|
21
|
+
end
|
22
|
+
|
23
|
+
alias_method :ast, :to_ast
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'dry/logic/operators'
|
2
4
|
|
3
5
|
require 'dry/schema/macros/core'
|
@@ -68,8 +70,7 @@ module Dry
|
|
68
70
|
#
|
69
71
|
# @api public
|
70
72
|
def array(*args, &block)
|
71
|
-
|
72
|
-
append_macro(Macros::Each) do |macro|
|
73
|
+
append_macro(Macros::Array) do |macro|
|
73
74
|
macro.value(*args, &block)
|
74
75
|
end
|
75
76
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'dry/schema/macros/value'
|
2
4
|
|
3
5
|
module Dry
|
@@ -9,11 +11,11 @@ module Dry
|
|
9
11
|
class Filled < Value
|
10
12
|
def call(*predicates, **opts, &block)
|
11
13
|
if predicates.include?(:empty?)
|
12
|
-
raise ::Dry::Schema::InvalidSchemaError,
|
14
|
+
raise ::Dry::Schema::InvalidSchemaError, 'Using filled with empty? predicate is invalid'
|
13
15
|
end
|
14
16
|
|
15
17
|
if predicates.include?(:filled?)
|
16
|
-
raise ::Dry::Schema::InvalidSchemaError,
|
18
|
+
raise ::Dry::Schema::InvalidSchemaError, 'Using filled with filled? is redundant'
|
17
19
|
end
|
18
20
|
|
19
21
|
if opts[:type_spec].equal?(true)
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'dry/schema/predicate_inferrer'
|
2
4
|
require 'dry/schema/processor'
|
3
5
|
require 'dry/schema/macros/dsl'
|
@@ -104,9 +106,11 @@ module Dry
|
|
104
106
|
def extract_type_spec(*args, nullable: false)
|
105
107
|
type_spec = args[0]
|
106
108
|
|
107
|
-
|
108
|
-
|
109
|
-
|
109
|
+
is_type_spec = type_spec.kind_of?(Dry::Schema::Processor) ||
|
110
|
+
type_spec.is_a?(Symbol) &&
|
111
|
+
type_spec.to_s.end_with?(QUESTION_MARK)
|
112
|
+
|
113
|
+
type_spec = nil if is_type_spec
|
110
114
|
|
111
115
|
predicates = Array(type_spec ? args[1..-1] : args)
|
112
116
|
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'dry/schema/macros/dsl'
|
2
4
|
|
3
5
|
module Dry
|
@@ -10,11 +12,11 @@ module Dry
|
|
10
12
|
# @api private
|
11
13
|
def call(*args, **opts, &block)
|
12
14
|
if args.include?(:empty?)
|
13
|
-
raise ::Dry::Schema::InvalidSchemaError,
|
15
|
+
raise ::Dry::Schema::InvalidSchemaError, 'Using maybe with empty? predicate is invalid'
|
14
16
|
end
|
15
17
|
|
16
18
|
if args.include?(:nil?)
|
17
|
-
raise ::Dry::Schema::InvalidSchemaError,
|
19
|
+
raise ::Dry::Schema::InvalidSchemaError, 'Using maybe with nil? predicate is redundant'
|
18
20
|
end
|
19
21
|
|
20
22
|
value(*args, **opts, &block)
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'dry/schema/macros/dsl'
|
2
4
|
|
3
5
|
module Dry
|
@@ -13,13 +15,18 @@ module Dry
|
|
13
15
|
|
14
16
|
if schema
|
15
17
|
current_type = schema_dsl.types[name]
|
16
|
-
|
18
|
+
|
19
|
+
updated_type =
|
20
|
+
if current_type.respond_to?(:of)
|
21
|
+
current_type.of(schema.type_schema)
|
22
|
+
else
|
23
|
+
schema.type_schema
|
24
|
+
end
|
17
25
|
|
18
26
|
schema_dsl.set_type(name, updated_type)
|
19
27
|
end
|
20
28
|
|
21
|
-
trace.evaluate(*predicates, **opts
|
22
|
-
|
29
|
+
trace.evaluate(*predicates, **opts)
|
23
30
|
trace.append(new(chain: false).instance_exec(&block)) if block
|
24
31
|
|
25
32
|
if trace.captures.empty?
|
data/lib/dry/schema/message.rb
CHANGED
@@ -1,4 +1,7 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'dry/equalizer'
|
4
|
+
require 'dry/schema/path'
|
2
5
|
|
3
6
|
module Dry
|
4
7
|
module Schema
|
@@ -86,6 +89,17 @@ module Dry
|
|
86
89
|
def eql?(other)
|
87
90
|
other.is_a?(String) ? text == other : super
|
88
91
|
end
|
92
|
+
|
93
|
+
def <=>(other)
|
94
|
+
l_path = Path[path]
|
95
|
+
r_path = Path[other.path]
|
96
|
+
|
97
|
+
unless l_path.include?(r_path)
|
98
|
+
raise ArgumentError, 'Cannot compare messages from different root paths'
|
99
|
+
end
|
100
|
+
|
101
|
+
l_path <=> r_path
|
102
|
+
end
|
89
103
|
end
|
90
104
|
end
|
91
105
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'dry/schema/constants'
|
2
4
|
require 'dry/schema/message'
|
3
5
|
require 'dry/schema/message_set'
|
@@ -12,7 +14,7 @@ module Dry
|
|
12
14
|
attr_reader :messages, :options, :locale, :default_lookup_options
|
13
15
|
|
14
16
|
EMPTY_OPTS = VisitorOpts.new
|
15
|
-
LIST_SEPARATOR = ', '
|
17
|
+
LIST_SEPARATOR = ', '
|
16
18
|
|
17
19
|
# @api private
|
18
20
|
def initialize(messages, options = {})
|
@@ -83,7 +85,7 @@ module Dry
|
|
83
85
|
elsif right.is_a?(Array)
|
84
86
|
right
|
85
87
|
else
|
86
|
-
[left, right]
|
88
|
+
[left, right].flatten.max
|
87
89
|
end
|
88
90
|
end
|
89
91
|
|
data/lib/dry/schema/messages.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'pathname'
|
2
4
|
require 'concurrent/map'
|
3
5
|
require 'dry/equalizer'
|
@@ -19,7 +21,7 @@ module Dry
|
|
19
21
|
DEFAULT_PATH = Pathname(__dir__).join('../../../../config/errors.yml').realpath.freeze
|
20
22
|
|
21
23
|
setting :paths, [DEFAULT_PATH]
|
22
|
-
setting :root, 'errors'
|
24
|
+
setting :root, 'errors'
|
23
25
|
setting :lookup_options, [:root, :predicate, :path, :val_type, :arg_type].freeze
|
24
26
|
|
25
27
|
setting :lookup_paths, %w(
|
@@ -38,8 +40,8 @@ module Dry
|
|
38
40
|
rules.%{name}
|
39
41
|
).freeze
|
40
42
|
|
41
|
-
setting :arg_type_default, 'default'
|
42
|
-
setting :val_type_default, 'default'
|
43
|
+
setting :arg_type_default, 'default'
|
44
|
+
setting :val_type_default, 'default'
|
43
45
|
|
44
46
|
setting :arg_types, Hash.new { |*| config.arg_type_default }.update(
|
45
47
|
Range => 'range'
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'i18n'
|
2
4
|
require 'dry/schema/messages/abstract'
|
3
5
|
|
@@ -10,7 +12,7 @@ module Dry
|
|
10
12
|
attr_reader :t
|
11
13
|
|
12
14
|
configure do |config|
|
13
|
-
config.root = 'dry_schema.errors'
|
15
|
+
config.root = 'dry_schema.errors'
|
14
16
|
config.rule_lookup_paths = config.rule_lookup_paths.map { |path| "dry_schema.#{path}" }
|
15
17
|
end
|
16
18
|
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Dry
|
2
4
|
module Schema
|
3
5
|
module Messages
|
@@ -60,7 +62,7 @@ module Dry
|
|
60
62
|
|
61
63
|
def rule_lookup_paths(tokens)
|
62
64
|
base_paths = messages.rule_lookup_paths(tokens)
|
63
|
-
base_paths.map { |key| key.gsub(
|
65
|
+
base_paths.map { |key| key.gsub('dry_schema', "dry_schema.#{namespace}") } + base_paths
|
64
66
|
end
|
65
67
|
end
|
66
68
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'yaml'
|
2
4
|
require 'pathname'
|
3
5
|
|
@@ -16,8 +18,10 @@ module Dry
|
|
16
18
|
|
17
19
|
# @api private
|
18
20
|
configure do |config|
|
19
|
-
config.root = '%{locale}.dry_schema.errors'
|
20
|
-
config.rule_lookup_paths = config.rule_lookup_paths.map { |path|
|
21
|
+
config.root = '%{locale}.dry_schema.errors'
|
22
|
+
config.rule_lookup_paths = config.rule_lookup_paths.map { |path|
|
23
|
+
"%{locale}.dry_schema.#{path}"
|
24
|
+
}
|
21
25
|
end
|
22
26
|
|
23
27
|
# @api private
|
@@ -32,7 +36,7 @@ module Dry
|
|
32
36
|
|
33
37
|
# @api private
|
34
38
|
def self.flat_hash(h, f = [], g = {})
|
35
|
-
return g.update(f.join('.'
|
39
|
+
return g.update(f.join('.') => h) unless h.is_a? Hash
|
36
40
|
h.each { |k, r| flat_hash(r, f + [k], g) }
|
37
41
|
g
|
38
42
|
end
|
data/lib/dry/schema/params.rb
CHANGED
data/lib/dry/schema/path.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'dry/schema/constants'
|
2
4
|
|
3
5
|
module Dry
|
@@ -6,6 +8,8 @@ module Dry
|
|
6
8
|
#
|
7
9
|
# @api private
|
8
10
|
class Path
|
11
|
+
include Enumerable
|
12
|
+
|
9
13
|
# !@attribute [r] keys
|
10
14
|
# @return [Array<Symbol>]
|
11
15
|
attr_reader :keys
|
@@ -47,8 +51,23 @@ module Dry
|
|
47
51
|
end
|
48
52
|
|
49
53
|
# @api private
|
50
|
-
def
|
51
|
-
keys
|
54
|
+
def each(&block)
|
55
|
+
keys.each(&block)
|
56
|
+
end
|
57
|
+
|
58
|
+
# @api private
|
59
|
+
def index(key)
|
60
|
+
keys.index(key)
|
61
|
+
end
|
62
|
+
|
63
|
+
# @api private
|
64
|
+
def include?(other)
|
65
|
+
!find { |key| (idx = other.index(key)) && keys[idx].equal?(key) }.nil?
|
66
|
+
end
|
67
|
+
|
68
|
+
# @api private
|
69
|
+
def <=>(other)
|
70
|
+
keys.count <=> other.count
|
52
71
|
end
|
53
72
|
end
|
54
73
|
end
|
data/lib/dry/schema/predicate.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'dry/core/cache'
|
2
4
|
|
3
5
|
module Dry
|
@@ -9,23 +11,71 @@ module Dry
|
|
9
11
|
class PredicateInferrer
|
10
12
|
extend Dry::Core::Cache
|
11
13
|
|
12
|
-
TYPE_TO_PREDICATE =
|
13
|
-
primitive = type.meta[:maybe] ? type.right.primitive : type.primitive
|
14
|
-
|
15
|
-
if hash.key?(primitive)
|
16
|
-
hash[primitive]
|
17
|
-
else
|
18
|
-
:"#{primitive.name.split('::').last.downcase}?"
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
TYPE_TO_PREDICATE.update(
|
14
|
+
TYPE_TO_PREDICATE = {
|
23
15
|
FalseClass => :false?,
|
24
16
|
Integer => :int?,
|
25
17
|
NilClass => :nil?,
|
26
18
|
String => :str?,
|
27
19
|
TrueClass => :true?
|
28
|
-
|
20
|
+
}.freeze
|
21
|
+
|
22
|
+
REDUCED_TYPES = {
|
23
|
+
%i[true? false?] => :bool?
|
24
|
+
}.freeze
|
25
|
+
|
26
|
+
# Compiler reduces type AST into a list of predicates
|
27
|
+
#
|
28
|
+
# @api private
|
29
|
+
class Compiler
|
30
|
+
def visit(node)
|
31
|
+
meth, rest = node
|
32
|
+
public_send(:"visit_#{meth}", rest)
|
33
|
+
end
|
34
|
+
|
35
|
+
def visit_definition(node)
|
36
|
+
type = node[0]
|
37
|
+
|
38
|
+
TYPE_TO_PREDICATE.fetch(type) {
|
39
|
+
:"#{type.name.split('::').last.downcase}?"
|
40
|
+
}
|
41
|
+
end
|
42
|
+
|
43
|
+
def visit_array(*)
|
44
|
+
:array?
|
45
|
+
end
|
46
|
+
|
47
|
+
def visit_safe(node)
|
48
|
+
other, * = node
|
49
|
+
visit(other)
|
50
|
+
end
|
51
|
+
|
52
|
+
def visit_constructor(node)
|
53
|
+
other, * = node
|
54
|
+
visit(other)
|
55
|
+
end
|
56
|
+
|
57
|
+
def visit_enum(node)
|
58
|
+
other, * = node
|
59
|
+
visit(other)
|
60
|
+
end
|
61
|
+
|
62
|
+
def visit_sum(node)
|
63
|
+
left, right = node
|
64
|
+
|
65
|
+
predicates = [visit(left), visit(right)]
|
66
|
+
|
67
|
+
if predicates.first == :nil?
|
68
|
+
predicates[1..predicates.size - 1]
|
69
|
+
else
|
70
|
+
predicates
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def visit_constrained(node)
|
75
|
+
other, * = node
|
76
|
+
visit(other)
|
77
|
+
end
|
78
|
+
end
|
29
79
|
|
30
80
|
# Infer predicate identifier from the provided type
|
31
81
|
#
|
@@ -34,16 +84,15 @@ module Dry
|
|
34
84
|
# @api private
|
35
85
|
def self.[](type)
|
36
86
|
fetch_or_store(type.hash) {
|
37
|
-
predicates =
|
38
|
-
|
39
|
-
[self[type.left], self[type.right]]
|
40
|
-
else
|
41
|
-
TYPE_TO_PREDICATE[type]
|
42
|
-
end
|
43
|
-
|
44
|
-
Array(predicates).flatten
|
87
|
+
predicates = Array(compiler.visit(type.to_ast)).flatten
|
88
|
+
Array(REDUCED_TYPES[predicates] || predicates).flatten
|
45
89
|
}
|
46
90
|
end
|
91
|
+
|
92
|
+
# @api private
|
93
|
+
def self.compiler
|
94
|
+
@compiler ||= Compiler.new
|
95
|
+
end
|
47
96
|
end
|
48
97
|
end
|
49
98
|
end
|
data/lib/dry/schema/processor.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'dry/configurable'
|
2
4
|
require 'dry/initializer'
|
3
5
|
|
@@ -113,6 +115,15 @@ module Dry
|
|
113
115
|
@__type_schema__ ||= steps.detect { |s| s.is_a?(ValueCoercer) }.type_schema
|
114
116
|
end
|
115
117
|
|
118
|
+
# Return the rules config
|
119
|
+
#
|
120
|
+
# @return [Dry::Types::Config]
|
121
|
+
#
|
122
|
+
# @api private
|
123
|
+
def config
|
124
|
+
@__config__ ||= steps.detect { |s| s.is_a?(RuleApplier) }.config
|
125
|
+
end
|
126
|
+
|
116
127
|
# Return AST representation of the rules
|
117
128
|
#
|
118
129
|
# @api private
|
data/lib/dry/schema/result.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'dry/initializer'
|
2
4
|
require 'dry/equalizer'
|
3
5
|
|
@@ -76,7 +78,7 @@ module Dry
|
|
76
78
|
#
|
77
79
|
# @api public
|
78
80
|
def error?(spec)
|
79
|
-
message_set.any? { |msg| Path[
|
81
|
+
message_set.any? { |msg| Path[msg.path].include?(Path[spec]) }
|
80
82
|
end
|
81
83
|
|
82
84
|
# Check if the result is successful
|
data/lib/dry/schema/trace.rb
CHANGED
data/lib/dry/schema/types.rb
CHANGED
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: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Piotr Solnica
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-03-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: concurrent-ruby
|
@@ -44,6 +44,26 @@ dependencies:
|
|
44
44
|
- - ">="
|
45
45
|
- !ruby/object:Gem::Version
|
46
46
|
version: 0.1.3
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: dry-core
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - "~>"
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0.2'
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: 0.2.1
|
57
|
+
type: :runtime
|
58
|
+
prerelease: false
|
59
|
+
version_requirements: !ruby/object:Gem::Requirement
|
60
|
+
requirements:
|
61
|
+
- - "~>"
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
version: '0.2'
|
64
|
+
- - ">="
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: 0.2.1
|
47
67
|
- !ruby/object:Gem::Dependency
|
48
68
|
name: dry-equalizer
|
49
69
|
requirement: !ruby/object:Gem::Requirement
|
@@ -112,26 +132,6 @@ dependencies:
|
|
112
132
|
- - "~>"
|
113
133
|
- !ruby/object:Gem::Version
|
114
134
|
version: '0.14'
|
115
|
-
- !ruby/object:Gem::Dependency
|
116
|
-
name: dry-core
|
117
|
-
requirement: !ruby/object:Gem::Requirement
|
118
|
-
requirements:
|
119
|
-
- - "~>"
|
120
|
-
- !ruby/object:Gem::Version
|
121
|
-
version: '0.2'
|
122
|
-
- - ">="
|
123
|
-
- !ruby/object:Gem::Version
|
124
|
-
version: 0.2.1
|
125
|
-
type: :runtime
|
126
|
-
prerelease: false
|
127
|
-
version_requirements: !ruby/object:Gem::Requirement
|
128
|
-
requirements:
|
129
|
-
- - "~>"
|
130
|
-
- !ruby/object:Gem::Version
|
131
|
-
version: '0.2'
|
132
|
-
- - ">="
|
133
|
-
- !ruby/object:Gem::Version
|
134
|
-
version: 0.2.1
|
135
135
|
- !ruby/object:Gem::Dependency
|
136
136
|
name: bundler
|
137
137
|
requirement: !ruby/object:Gem::Requirement
|
@@ -202,6 +202,7 @@ files:
|
|
202
202
|
- lib/dry/schema/key_coercer.rb
|
203
203
|
- lib/dry/schema/key_map.rb
|
204
204
|
- lib/dry/schema/macros.rb
|
205
|
+
- lib/dry/schema/macros/array.rb
|
205
206
|
- lib/dry/schema/macros/core.rb
|
206
207
|
- lib/dry/schema/macros/dsl.rb
|
207
208
|
- lib/dry/schema/macros/each.rb
|
@@ -249,7 +250,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
249
250
|
requirements:
|
250
251
|
- - ">="
|
251
252
|
- !ruby/object:Gem::Version
|
252
|
-
version: '2.
|
253
|
+
version: '2.3'
|
253
254
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
254
255
|
requirements:
|
255
256
|
- - ">="
|