dry-validation 1.0.0 → 1.5.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +379 -141
- data/LICENSE +1 -1
- data/README.md +7 -8
- data/dry-validation.gemspec +41 -0
- data/lib/dry-validation.rb +1 -1
- data/lib/dry/validation.rb +10 -5
- data/lib/dry/validation/config.rb +2 -2
- data/lib/dry/validation/constants.rb +9 -2
- data/lib/dry/validation/contract.rb +34 -17
- data/lib/dry/validation/contract/class_interface.rb +62 -56
- data/lib/dry/validation/evaluator.rb +50 -13
- data/lib/dry/validation/extensions/hints.rb +1 -3
- data/lib/dry/validation/extensions/monads.rb +1 -1
- data/lib/dry/validation/extensions/predicates_as_macros.rb +75 -0
- data/lib/dry/validation/failures.rb +15 -3
- data/lib/dry/validation/function.rb +13 -10
- data/lib/dry/validation/macro.rb +2 -2
- data/lib/dry/validation/macros.rb +3 -3
- data/lib/dry/validation/message.rb +4 -4
- data/lib/dry/validation/message_set.rb +6 -51
- data/lib/dry/validation/messages/resolver.rb +60 -5
- data/lib/dry/validation/result.rb +47 -8
- data/lib/dry/validation/rule.rb +43 -12
- data/lib/dry/validation/schema_ext.rb +19 -0
- data/lib/dry/validation/values.rb +38 -11
- data/lib/dry/validation/version.rb +1 -1
- metadata +31 -24
data/lib/dry/validation/rule.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "dry/equalizer"
|
4
4
|
|
5
|
-
require
|
6
|
-
require
|
5
|
+
require "dry/validation/constants"
|
6
|
+
require "dry/validation/function"
|
7
7
|
|
8
8
|
module Dry
|
9
9
|
module Validation
|
@@ -54,7 +54,7 @@ module Dry
|
|
54
54
|
#
|
55
55
|
# @api public
|
56
56
|
def validate(*macros, &block)
|
57
|
-
@macros = macros
|
57
|
+
@macros = parse_macros(*macros)
|
58
58
|
@block = block if block
|
59
59
|
self
|
60
60
|
end
|
@@ -65,29 +65,38 @@ module Dry
|
|
65
65
|
# for a given array item.
|
66
66
|
#
|
67
67
|
# @example
|
68
|
-
# rule(:nums).each do
|
69
|
-
# key.failure("must be greater than 0") if value < 0
|
68
|
+
# rule(:nums).each do |index:|
|
69
|
+
# key([:number, index]).failure("must be greater than 0") if value < 0
|
70
|
+
# end
|
71
|
+
# rule(:nums).each(min: 3)
|
72
|
+
# rule(address: :city) do
|
73
|
+
# key.failure("oops") if value != 'Munich'
|
70
74
|
# end
|
71
75
|
#
|
72
76
|
# @return [Rule]
|
73
77
|
#
|
74
78
|
# @api public
|
75
79
|
def each(*macros, &block)
|
76
|
-
root = keys
|
80
|
+
root = keys[0]
|
81
|
+
macros = parse_macros(*macros)
|
77
82
|
@keys = []
|
78
83
|
|
79
84
|
@block = proc do
|
80
|
-
|
81
|
-
|
85
|
+
unless result.base_error?(root) || !values.key?(root)
|
86
|
+
values[root].each_with_index do |_, idx|
|
87
|
+
path = [*Schema::Path[root].to_a, idx]
|
82
88
|
|
83
|
-
|
89
|
+
next if result.schema_error?(path)
|
84
90
|
|
85
|
-
|
91
|
+
evaluator = with(macros: macros, keys: [path], index: idx, &block)
|
86
92
|
|
87
|
-
|
93
|
+
failures.concat(evaluator.failures)
|
94
|
+
end
|
88
95
|
end
|
89
96
|
end
|
90
97
|
|
98
|
+
@block_options = map_keywords(block) if block
|
99
|
+
|
91
100
|
self
|
92
101
|
end
|
93
102
|
|
@@ -99,6 +108,28 @@ module Dry
|
|
99
108
|
def inspect
|
100
109
|
%(#<#{self.class} keys=#{keys.inspect}>)
|
101
110
|
end
|
111
|
+
|
112
|
+
# Parse function arguments into macros structure
|
113
|
+
#
|
114
|
+
# @return [Array]
|
115
|
+
#
|
116
|
+
# @api private
|
117
|
+
def parse_macros(*args)
|
118
|
+
args.each_with_object([]) do |spec, macros|
|
119
|
+
case spec
|
120
|
+
when Hash
|
121
|
+
add_macro_from_hash(macros, spec)
|
122
|
+
else
|
123
|
+
macros << Array(spec)
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
def add_macro_from_hash(macros, spec)
|
129
|
+
spec.each do |k, v|
|
130
|
+
macros << [k, v.is_a?(Array) ? v : [v]]
|
131
|
+
end
|
132
|
+
end
|
102
133
|
end
|
103
134
|
end
|
104
135
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "dry/schema/path"
|
4
|
+
|
5
|
+
module Dry
|
6
|
+
module Schema
|
7
|
+
class Path
|
8
|
+
# @api private
|
9
|
+
def multi_value?
|
10
|
+
last.is_a?(Array)
|
11
|
+
end
|
12
|
+
|
13
|
+
# @api private
|
14
|
+
def expand
|
15
|
+
to_a[0..-2].product(last).map { |spec| self.class[spec] }
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -1,7 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
3
|
+
require "dry/equalizer"
|
4
|
+
require "dry/schema/path"
|
5
|
+
require "dry/validation/constants"
|
5
6
|
|
6
7
|
module Dry
|
7
8
|
module Validation
|
@@ -34,23 +35,48 @@ module Dry
|
|
34
35
|
# key.failure('must be > 18') if values[:age] <= 18
|
35
36
|
# end
|
36
37
|
#
|
37
|
-
# @param [Symbol]
|
38
|
+
# @param args [Symbol, String, Hash, Array<Symbol>] If given as a single
|
39
|
+
# Symbol, String, Array or Hash, build a key array using
|
40
|
+
# {Dry::Schema::Path} digging for data. If given as positional
|
41
|
+
# arguments, use these with Hash#dig on the data directly.
|
38
42
|
#
|
39
43
|
# @return [Object]
|
40
44
|
#
|
41
45
|
# @api public
|
42
46
|
def [](*args)
|
43
|
-
if args.size
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
47
|
+
return data.dig(*args) if args.size > 1
|
48
|
+
|
49
|
+
case (key = args[0])
|
50
|
+
when Symbol, String, Array, Hash
|
51
|
+
keys = Schema::Path[key].to_a
|
52
|
+
|
53
|
+
return data.dig(*keys) unless keys.last.is_a?(Array)
|
54
|
+
|
55
|
+
last = keys.pop
|
56
|
+
vals = self.class.new(data.dig(*keys))
|
57
|
+
vals.fetch_values(*last) { nil }
|
58
|
+
else
|
59
|
+
raise ArgumentError, "+key+ must be a valid path specification"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
# @api public
|
64
|
+
def key?(key, hash = data)
|
65
|
+
return hash.key?(key) if key.is_a?(Symbol)
|
66
|
+
|
67
|
+
Schema::Path[key].reduce(hash) do |a, e|
|
68
|
+
if e.is_a?(Array)
|
69
|
+
result = e.all? { |k| key?(k, a) }
|
70
|
+
return result
|
71
|
+
elsif e.is_a?(Symbol) && a.is_a?(Array)
|
72
|
+
return false
|
48
73
|
else
|
49
|
-
|
74
|
+
return false unless a.is_a?(Array) ? (e >= 0 && e < a.size) : a.key?(e)
|
50
75
|
end
|
51
|
-
|
52
|
-
data.dig(*args)
|
76
|
+
a[e]
|
53
77
|
end
|
78
|
+
|
79
|
+
true
|
54
80
|
end
|
55
81
|
|
56
82
|
# @api private
|
@@ -68,6 +94,7 @@ module Dry
|
|
68
94
|
super
|
69
95
|
end
|
70
96
|
end
|
97
|
+
ruby2_keywords(:method_missing) if respond_to?(:ruby2_keywords, true)
|
71
98
|
end
|
72
99
|
end
|
73
100
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dry-validation
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.5.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Piotr Solnica
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-09-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: concurrent-ruby
|
@@ -25,53 +25,53 @@ dependencies:
|
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '1.0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name: dry-
|
28
|
+
name: dry-container
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '0.
|
33
|
+
version: '0.7'
|
34
|
+
- - ">="
|
35
|
+
- !ruby/object:Gem::Version
|
36
|
+
version: 0.7.1
|
34
37
|
type: :runtime
|
35
38
|
prerelease: false
|
36
39
|
version_requirements: !ruby/object:Gem::Requirement
|
37
40
|
requirements:
|
38
41
|
- - "~>"
|
39
42
|
- !ruby/object:Gem::Version
|
40
|
-
version: '0.
|
43
|
+
version: '0.7'
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: 0.7.1
|
41
47
|
- !ruby/object:Gem::Dependency
|
42
|
-
name: dry-
|
48
|
+
name: dry-core
|
43
49
|
requirement: !ruby/object:Gem::Requirement
|
44
50
|
requirements:
|
45
51
|
- - "~>"
|
46
52
|
- !ruby/object:Gem::Version
|
47
|
-
version: '0.
|
53
|
+
version: '0.4'
|
48
54
|
type: :runtime
|
49
55
|
prerelease: false
|
50
56
|
version_requirements: !ruby/object:Gem::Requirement
|
51
57
|
requirements:
|
52
58
|
- - "~>"
|
53
59
|
- !ruby/object:Gem::Version
|
54
|
-
version: '0.
|
60
|
+
version: '0.4'
|
55
61
|
- !ruby/object:Gem::Dependency
|
56
|
-
name: dry-
|
62
|
+
name: dry-equalizer
|
57
63
|
requirement: !ruby/object:Gem::Requirement
|
58
64
|
requirements:
|
59
65
|
- - "~>"
|
60
66
|
- !ruby/object:Gem::Version
|
61
|
-
version: '0.
|
62
|
-
- - ">="
|
63
|
-
- !ruby/object:Gem::Version
|
64
|
-
version: 0.7.1
|
67
|
+
version: '0.2'
|
65
68
|
type: :runtime
|
66
69
|
prerelease: false
|
67
70
|
version_requirements: !ruby/object:Gem::Requirement
|
68
71
|
requirements:
|
69
72
|
- - "~>"
|
70
73
|
- !ruby/object:Gem::Version
|
71
|
-
version: '0.
|
72
|
-
- - ">="
|
73
|
-
- !ruby/object:Gem::Version
|
74
|
-
version: 0.7.1
|
74
|
+
version: '0.2'
|
75
75
|
- !ruby/object:Gem::Dependency
|
76
76
|
name: dry-initializer
|
77
77
|
requirement: !ruby/object:Gem::Requirement
|
@@ -92,20 +92,20 @@ dependencies:
|
|
92
92
|
requirements:
|
93
93
|
- - "~>"
|
94
94
|
- !ruby/object:Gem::Version
|
95
|
-
version: '1.
|
95
|
+
version: '1.5'
|
96
96
|
- - ">="
|
97
97
|
- !ruby/object:Gem::Version
|
98
|
-
version: 1.
|
98
|
+
version: 1.5.2
|
99
99
|
type: :runtime
|
100
100
|
prerelease: false
|
101
101
|
version_requirements: !ruby/object:Gem::Requirement
|
102
102
|
requirements:
|
103
103
|
- - "~>"
|
104
104
|
- !ruby/object:Gem::Version
|
105
|
-
version: '1.
|
105
|
+
version: '1.5'
|
106
106
|
- - ">="
|
107
107
|
- !ruby/object:Gem::Version
|
108
|
-
version: 1.
|
108
|
+
version: 1.5.2
|
109
109
|
- !ruby/object:Gem::Dependency
|
110
110
|
name: bundler
|
111
111
|
requirement: !ruby/object:Gem::Requirement
|
@@ -148,7 +148,7 @@ dependencies:
|
|
148
148
|
- - ">="
|
149
149
|
- !ruby/object:Gem::Version
|
150
150
|
version: '0'
|
151
|
-
description:
|
151
|
+
description: Validation library
|
152
152
|
email:
|
153
153
|
- piotr.solnica@gmail.com
|
154
154
|
executables: []
|
@@ -159,6 +159,7 @@ files:
|
|
159
159
|
- LICENSE
|
160
160
|
- README.md
|
161
161
|
- config/errors.yml
|
162
|
+
- dry-validation.gemspec
|
162
163
|
- lib/dry-validation.rb
|
163
164
|
- lib/dry/validation.rb
|
164
165
|
- lib/dry/validation/config.rb
|
@@ -168,6 +169,7 @@ files:
|
|
168
169
|
- lib/dry/validation/evaluator.rb
|
169
170
|
- lib/dry/validation/extensions/hints.rb
|
170
171
|
- lib/dry/validation/extensions/monads.rb
|
172
|
+
- lib/dry/validation/extensions/predicates_as_macros.rb
|
171
173
|
- lib/dry/validation/failures.rb
|
172
174
|
- lib/dry/validation/function.rb
|
173
175
|
- lib/dry/validation/macro.rb
|
@@ -177,12 +179,17 @@ files:
|
|
177
179
|
- lib/dry/validation/messages/resolver.rb
|
178
180
|
- lib/dry/validation/result.rb
|
179
181
|
- lib/dry/validation/rule.rb
|
182
|
+
- lib/dry/validation/schema_ext.rb
|
180
183
|
- lib/dry/validation/values.rb
|
181
184
|
- lib/dry/validation/version.rb
|
182
185
|
homepage: https://dry-rb.org/gems/dry-validation
|
183
186
|
licenses:
|
184
187
|
- MIT
|
185
|
-
metadata:
|
188
|
+
metadata:
|
189
|
+
allowed_push_host: https://rubygems.org
|
190
|
+
changelog_uri: https://github.com/dry-rb/dry-validation/blob/master/CHANGELOG.md
|
191
|
+
source_code_uri: https://github.com/dry-rb/dry-validation
|
192
|
+
bug_tracker_uri: https://github.com/dry-rb/dry-validation/issues
|
186
193
|
post_install_message:
|
187
194
|
rdoc_options: []
|
188
195
|
require_paths:
|
@@ -191,7 +198,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
191
198
|
requirements:
|
192
199
|
- - ">="
|
193
200
|
- !ruby/object:Gem::Version
|
194
|
-
version:
|
201
|
+
version: 2.4.0
|
195
202
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
196
203
|
requirements:
|
197
204
|
- - ">="
|