dry-types 1.8.3 → 1.9.0
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 +185 -226
- data/LICENSE +1 -1
- data/README.md +7 -13
- data/dry-types.gemspec +24 -18
- data/lib/dry/types/any.rb +1 -1
- data/lib/dry/types/array/member.rb +3 -5
- data/lib/dry/types/builder.rb +18 -2
- data/lib/dry/types/coercions/params.rb +4 -4
- data/lib/dry/types/coercions.rb +8 -8
- data/lib/dry/types/compiler.rb +10 -3
- data/lib/dry/types/constructor/function.rb +6 -6
- data/lib/dry/types/constructor/wrapper.rb +2 -2
- data/lib/dry/types/constructor.rb +4 -4
- data/lib/dry/types/hash.rb +3 -3
- data/lib/dry/types/map.rb +1 -1
- data/lib/dry/types/meta.rb +7 -1
- data/lib/dry/types/nominal.rb +25 -1
- data/lib/dry/types/options.rb +5 -1
- data/lib/dry/types/params.rb +20 -49
- data/lib/dry/types/predicate_inferrer.rb +1 -1
- data/lib/dry/types/primitive_inferrer.rb +4 -16
- data/lib/dry/types/printer.rb +17 -1
- data/lib/dry/types/schema.rb +7 -7
- data/lib/dry/types/sum.rb +13 -0
- data/lib/dry/types/version.rb +1 -1
- data/lib/dry/types.rb +14 -15
- metadata +69 -13
data/LICENSE
CHANGED
data/README.md
CHANGED
|
@@ -1,23 +1,17 @@
|
|
|
1
|
-
<!---
|
|
1
|
+
<!--- This file is synced from hanakai-rb/repo-sync -->
|
|
2
2
|
|
|
3
|
-
[
|
|
3
|
+
[rubygem]: https://rubygems.org/gems/dry-types
|
|
4
4
|
[actions]: https://github.com/dry-rb/dry-types/actions
|
|
5
5
|
|
|
6
|
-
# dry-types [][
|
|
6
|
+
# dry-types [][rubygem] [][actions]
|
|
7
7
|
|
|
8
8
|
## Links
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
## Supported Ruby versions
|
|
15
|
-
|
|
16
|
-
This library officially supports the following Ruby versions:
|
|
17
|
-
|
|
18
|
-
* MRI `>= 3.1`
|
|
19
|
-
* jruby `>= 9.4` (not tested on CI)
|
|
10
|
+
- [User documentation](https://dry-rb.org/gems/dry-types)
|
|
11
|
+
- [API documentation](http://rubydoc.info/gems/dry-types)
|
|
12
|
+
- [Forum](https://discourse.dry-rb.org)
|
|
20
13
|
|
|
21
14
|
## License
|
|
22
15
|
|
|
23
16
|
See `LICENSE` file.
|
|
17
|
+
|
data/dry-types.gemspec
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
#
|
|
3
|
+
# This file is synced from hanakai-rb/repo-sync. To update it, edit repo-sync.yml.
|
|
4
4
|
|
|
5
5
|
lib = File.expand_path("lib", __dir__)
|
|
6
6
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
@@ -8,8 +8,8 @@ require "dry/types/version"
|
|
|
8
8
|
|
|
9
9
|
Gem::Specification.new do |spec|
|
|
10
10
|
spec.name = "dry-types"
|
|
11
|
-
spec.authors = ["
|
|
12
|
-
spec.email = ["
|
|
11
|
+
spec.authors = ["Hanakai team"]
|
|
12
|
+
spec.email = ["info@hanakai.org"]
|
|
13
13
|
spec.license = "MIT"
|
|
14
14
|
spec.version = Dry::Types::VERSION.dup
|
|
15
15
|
|
|
@@ -21,19 +21,25 @@ Gem::Specification.new do |spec|
|
|
|
21
21
|
spec.executables = []
|
|
22
22
|
spec.require_paths = ["lib"]
|
|
23
23
|
|
|
24
|
-
spec.
|
|
25
|
-
|
|
26
|
-
spec.metadata["
|
|
27
|
-
spec.metadata["
|
|
28
|
-
spec.metadata["
|
|
29
|
-
|
|
30
|
-
spec.
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
spec.
|
|
35
|
-
spec.
|
|
36
|
-
spec.
|
|
37
|
-
spec.
|
|
38
|
-
spec.
|
|
24
|
+
spec.extra_rdoc_files = ["README.md", "CHANGELOG.md", "LICENSE"]
|
|
25
|
+
|
|
26
|
+
spec.metadata["allowed_push_host"] = "https://rubygems.org"
|
|
27
|
+
spec.metadata["changelog_uri"] = "https://github.com/dry-rb/dry-types/blob/main/CHANGELOG.md"
|
|
28
|
+
spec.metadata["source_code_uri"] = "https://github.com/dry-rb/dry-types"
|
|
29
|
+
spec.metadata["bug_tracker_uri"] = "https://github.com/dry-rb/dry-types/issues"
|
|
30
|
+
spec.metadata["funding_uri"] = "https://github.com/sponsors/hanami"
|
|
31
|
+
|
|
32
|
+
spec.required_ruby_version = ">= 3.2"
|
|
33
|
+
|
|
34
|
+
spec.add_runtime_dependency "bigdecimal", ">= 3.0"
|
|
35
|
+
spec.add_runtime_dependency "concurrent-ruby", "~> 1.0"
|
|
36
|
+
spec.add_runtime_dependency "dry-core", "~> 1.0"
|
|
37
|
+
spec.add_runtime_dependency "dry-inflector", "~> 1.0"
|
|
38
|
+
spec.add_runtime_dependency "dry-logic", "~> 1.4"
|
|
39
|
+
spec.add_runtime_dependency "zeitwerk", "~> 2.6"
|
|
40
|
+
spec.add_development_dependency "bundler"
|
|
41
|
+
spec.add_development_dependency "rake"
|
|
42
|
+
spec.add_development_dependency "rspec"
|
|
43
|
+
spec.add_development_dependency "yard"
|
|
39
44
|
end
|
|
45
|
+
|
data/lib/dry/types/any.rb
CHANGED
|
@@ -97,18 +97,16 @@ module Dry
|
|
|
97
97
|
# @return [Lax]
|
|
98
98
|
#
|
|
99
99
|
# @api public
|
|
100
|
-
def lax
|
|
101
|
-
Lax.new(Member.new(primitive, **options, member: member.lax, meta: meta))
|
|
102
|
-
end
|
|
100
|
+
def lax = Lax.new(Member.new(primitive, **options, member: member.lax, meta: meta))
|
|
103
101
|
|
|
104
102
|
# @see Nominal#to_ast
|
|
105
103
|
#
|
|
106
104
|
# @api public
|
|
107
105
|
def to_ast(meta: true)
|
|
108
106
|
if member.respond_to?(:to_ast)
|
|
109
|
-
[:array, [member.to_ast(meta: meta), meta
|
|
107
|
+
[:array, [member.to_ast(meta: meta), meta_ast(meta)]]
|
|
110
108
|
else
|
|
111
|
-
[:array, [member, meta
|
|
109
|
+
[:array, [member, meta_ast(meta)]]
|
|
112
110
|
end
|
|
113
111
|
end
|
|
114
112
|
|
data/lib/dry/types/builder.rb
CHANGED
|
@@ -50,7 +50,16 @@ module Dry
|
|
|
50
50
|
# @return [Sum]
|
|
51
51
|
#
|
|
52
52
|
# @api public
|
|
53
|
-
def optional
|
|
53
|
+
def optional
|
|
54
|
+
nil_type =
|
|
55
|
+
if Types.use_namespaced_optionals && respond_to?(:namespace) && namespace
|
|
56
|
+
Types["#{namespace}.nil"]
|
|
57
|
+
else
|
|
58
|
+
Types["nil"]
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
nil_type | self
|
|
62
|
+
end
|
|
54
63
|
|
|
55
64
|
# Turn a type into a constrained type
|
|
56
65
|
#
|
|
@@ -77,8 +86,15 @@ module Dry
|
|
|
77
86
|
def default(input = Undefined, options = EMPTY_HASH, &block)
|
|
78
87
|
unless input.frozen? || options[:shared]
|
|
79
88
|
where = Core::Deprecations::STACK.()
|
|
89
|
+
|
|
90
|
+
# There is a weird behaviour in JRuby where the source_location is mutated upon
|
|
91
|
+
# calling `inspect` on proc (see: https://github.com/jruby/jruby/issues/9110)
|
|
92
|
+
# To bypass this, we call inspect on the clone (but only for proc and JRuby).
|
|
93
|
+
# This should be fixes in JRuby 10.0.3.0.
|
|
94
|
+
obj = input.is_a?(Proc) && RUBY_ENGINE == "jruby" ? input.dup : input
|
|
95
|
+
|
|
80
96
|
Core::Deprecations.warn(
|
|
81
|
-
"#{
|
|
97
|
+
"#{obj.inspect} is mutable. " \
|
|
82
98
|
"Be careful: types will return the same instance of the default " \
|
|
83
99
|
"value every time. Call `.freeze` when setting the default " \
|
|
84
100
|
"or pass `shared: true` to discard this warning." \
|
|
@@ -89,8 +89,8 @@ module Dry
|
|
|
89
89
|
else
|
|
90
90
|
Integer(input)
|
|
91
91
|
end
|
|
92
|
-
rescue ::ArgumentError, ::TypeError =>
|
|
93
|
-
CoercionError.handle(
|
|
92
|
+
rescue ::ArgumentError, ::TypeError => exception
|
|
93
|
+
CoercionError.handle(exception, &)
|
|
94
94
|
end
|
|
95
95
|
|
|
96
96
|
# @param [#to_f, Object] input
|
|
@@ -102,8 +102,8 @@ module Dry
|
|
|
102
102
|
# @api public
|
|
103
103
|
def self.to_float(input, &)
|
|
104
104
|
Float(input)
|
|
105
|
-
rescue ::ArgumentError, ::TypeError =>
|
|
106
|
-
CoercionError.handle(
|
|
105
|
+
rescue ::ArgumentError, ::TypeError => exception
|
|
106
|
+
CoercionError.handle(exception, &)
|
|
107
107
|
end
|
|
108
108
|
|
|
109
109
|
# @param [#to_d, Object] input
|
data/lib/dry/types/coercions.rb
CHANGED
|
@@ -19,8 +19,8 @@ module Dry
|
|
|
19
19
|
if input.respond_to?(:to_str)
|
|
20
20
|
begin
|
|
21
21
|
::Date.parse(input)
|
|
22
|
-
rescue ::ArgumentError, ::RangeError =>
|
|
23
|
-
CoercionError.handle(
|
|
22
|
+
rescue ::ArgumentError, ::RangeError => exception
|
|
23
|
+
CoercionError.handle(exception, &)
|
|
24
24
|
end
|
|
25
25
|
elsif input.is_a?(::Date)
|
|
26
26
|
input
|
|
@@ -42,8 +42,8 @@ module Dry
|
|
|
42
42
|
if input.respond_to?(:to_str)
|
|
43
43
|
begin
|
|
44
44
|
::DateTime.parse(input)
|
|
45
|
-
rescue ::ArgumentError =>
|
|
46
|
-
CoercionError.handle(
|
|
45
|
+
rescue ::ArgumentError => exception
|
|
46
|
+
CoercionError.handle(exception, &)
|
|
47
47
|
end
|
|
48
48
|
elsif input.is_a?(::DateTime)
|
|
49
49
|
input
|
|
@@ -65,8 +65,8 @@ module Dry
|
|
|
65
65
|
if input.respond_to?(:to_str)
|
|
66
66
|
begin
|
|
67
67
|
::Time.parse(input)
|
|
68
|
-
rescue ::ArgumentError =>
|
|
69
|
-
CoercionError.handle(
|
|
68
|
+
rescue ::ArgumentError => exception
|
|
69
|
+
CoercionError.handle(exception, &)
|
|
70
70
|
end
|
|
71
71
|
elsif input.is_a?(::Time)
|
|
72
72
|
input
|
|
@@ -86,8 +86,8 @@ module Dry
|
|
|
86
86
|
# @api public
|
|
87
87
|
def to_symbol(input, &)
|
|
88
88
|
input.to_sym
|
|
89
|
-
rescue ::NoMethodError =>
|
|
90
|
-
CoercionError.handle(
|
|
89
|
+
rescue ::NoMethodError => exception
|
|
90
|
+
CoercionError.handle(exception, &)
|
|
91
91
|
end
|
|
92
92
|
|
|
93
93
|
private
|
data/lib/dry/types/compiler.rb
CHANGED
|
@@ -37,13 +37,20 @@ module Dry
|
|
|
37
37
|
deprecate(:visit_safe, :visit_lax)
|
|
38
38
|
|
|
39
39
|
def visit_nominal(node)
|
|
40
|
-
type, meta =
|
|
40
|
+
type, options, meta =
|
|
41
|
+
case node
|
|
42
|
+
in [type, options, meta]
|
|
43
|
+
node
|
|
44
|
+
in [type, meta]
|
|
45
|
+
[type, EMPTY_HASH, meta]
|
|
46
|
+
end
|
|
47
|
+
|
|
41
48
|
nominal_name = "nominal.#{Types.identifier(type)}"
|
|
42
49
|
|
|
43
50
|
if registry.registered?(nominal_name)
|
|
44
|
-
registry[nominal_name].meta(meta)
|
|
51
|
+
registry[nominal_name].with(**options).meta(meta)
|
|
45
52
|
else
|
|
46
|
-
Nominal.new(type, meta: meta)
|
|
53
|
+
Nominal.new(type, meta: meta, **options)
|
|
47
54
|
end
|
|
48
55
|
end
|
|
49
56
|
|
|
@@ -15,8 +15,8 @@ module Dry
|
|
|
15
15
|
class Safe < Function
|
|
16
16
|
def call(input, &)
|
|
17
17
|
@fn.(input)
|
|
18
|
-
rescue ::NoMethodError, ::TypeError, ::ArgumentError =>
|
|
19
|
-
CoercionError.handle(
|
|
18
|
+
rescue ::NoMethodError, ::TypeError, ::ArgumentError => exception
|
|
19
|
+
CoercionError.handle(exception, &)
|
|
20
20
|
end
|
|
21
21
|
end
|
|
22
22
|
|
|
@@ -92,8 +92,8 @@ module Dry
|
|
|
92
92
|
class PrivateSafeCall < PrivateCall
|
|
93
93
|
def call(input, &)
|
|
94
94
|
@target.send(@name, input)
|
|
95
|
-
rescue ::NoMethodError, ::TypeError, ::ArgumentError =>
|
|
96
|
-
CoercionError.handle(
|
|
95
|
+
rescue ::NoMethodError, ::TypeError, ::ArgumentError => exception
|
|
96
|
+
CoercionError.handle(exception, &)
|
|
97
97
|
end
|
|
98
98
|
end
|
|
99
99
|
|
|
@@ -120,8 +120,8 @@ module Dry
|
|
|
120
120
|
# @return [Object]
|
|
121
121
|
def call(input, type, &)
|
|
122
122
|
@fn.(input, type, &)
|
|
123
|
-
rescue ::NoMethodError, ::TypeError, ::ArgumentError =>
|
|
124
|
-
CoercionError.handle(
|
|
123
|
+
rescue ::NoMethodError, ::TypeError, ::ArgumentError => exception
|
|
124
|
+
CoercionError.handle(exception, &)
|
|
125
125
|
end
|
|
126
126
|
alias_method :[], :call
|
|
127
127
|
|
|
@@ -24,8 +24,8 @@ module Dry
|
|
|
24
24
|
# @api public
|
|
25
25
|
def try(input, &)
|
|
26
26
|
value = fn.(input, type)
|
|
27
|
-
rescue CoercionError =>
|
|
28
|
-
failure = failure(input,
|
|
27
|
+
rescue CoercionError => exception
|
|
28
|
+
failure = failure(input, exception)
|
|
29
29
|
block_given? ? yield(failure) : failure
|
|
30
30
|
else
|
|
31
31
|
type.try(value, &)
|
|
@@ -15,7 +15,7 @@ module Dry
|
|
|
15
15
|
# @return [Type]
|
|
16
16
|
attr_reader :type
|
|
17
17
|
|
|
18
|
-
undef :constrained?, :meta, :optional?, :primitive, :default?, :name
|
|
18
|
+
undef :constrained?, :meta, :optional?, :primitive, :primitive?, :default?, :name, :namespace
|
|
19
19
|
|
|
20
20
|
# @param [Builder, Object] input
|
|
21
21
|
# @param [Hash] options
|
|
@@ -55,7 +55,7 @@ module Dry
|
|
|
55
55
|
# Instantiate a new constructor type instance
|
|
56
56
|
#
|
|
57
57
|
# @param [Type] type
|
|
58
|
-
# @
|
|
58
|
+
# @option [Function] fn
|
|
59
59
|
# @param [Hash] options
|
|
60
60
|
#
|
|
61
61
|
# @api private
|
|
@@ -88,8 +88,8 @@ module Dry
|
|
|
88
88
|
# @api public
|
|
89
89
|
def try(input, &)
|
|
90
90
|
value = fn.(input)
|
|
91
|
-
rescue CoercionError =>
|
|
92
|
-
failure = failure(input,
|
|
91
|
+
rescue CoercionError => exception
|
|
92
|
+
failure = failure(input, exception)
|
|
93
93
|
block_given? ? yield(failure) : failure
|
|
94
94
|
else
|
|
95
95
|
type.try(value, &)
|
data/lib/dry/types/hash.rb
CHANGED
|
@@ -94,8 +94,8 @@ module Dry
|
|
|
94
94
|
# @api public
|
|
95
95
|
def to_ast(meta: true)
|
|
96
96
|
[:hash,
|
|
97
|
-
[options.slice(:type_transform_fn),
|
|
98
|
-
meta
|
|
97
|
+
[options.slice(:type_transform_fn, :namespace),
|
|
98
|
+
meta_ast(meta)]]
|
|
99
99
|
end
|
|
100
100
|
|
|
101
101
|
private
|
|
@@ -117,7 +117,7 @@ module Dry
|
|
|
117
117
|
case type
|
|
118
118
|
when Type then type
|
|
119
119
|
when ::Class, ::String then Types[type]
|
|
120
|
-
else type
|
|
120
|
+
else type
|
|
121
121
|
end
|
|
122
122
|
end
|
|
123
123
|
|
data/lib/dry/types/map.rb
CHANGED
data/lib/dry/types/meta.rb
CHANGED
|
@@ -16,7 +16,13 @@ module Dry
|
|
|
16
16
|
# @return [Type]
|
|
17
17
|
#
|
|
18
18
|
# @api public
|
|
19
|
-
def with(**options)
|
|
19
|
+
def with(**options)
|
|
20
|
+
if options.empty?
|
|
21
|
+
self
|
|
22
|
+
else
|
|
23
|
+
super(meta: @meta, **options)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
20
26
|
|
|
21
27
|
# @overload meta
|
|
22
28
|
# @return [Hash] metadata associated with type
|
data/lib/dry/types/nominal.rb
CHANGED
|
@@ -18,6 +18,9 @@ module Dry
|
|
|
18
18
|
# @return [Class]
|
|
19
19
|
attr_reader :primitive
|
|
20
20
|
|
|
21
|
+
# @return [String, nil]
|
|
22
|
+
attr_reader :namespace
|
|
23
|
+
|
|
21
24
|
# @param [Class] primitive
|
|
22
25
|
#
|
|
23
26
|
# @return [Type]
|
|
@@ -42,6 +45,7 @@ module Dry
|
|
|
42
45
|
def initialize(primitive, **options)
|
|
43
46
|
super
|
|
44
47
|
@primitive = primitive
|
|
48
|
+
@namespace = options[:namespace]
|
|
45
49
|
freeze
|
|
46
50
|
end
|
|
47
51
|
|
|
@@ -152,7 +156,7 @@ module Dry
|
|
|
152
156
|
#
|
|
153
157
|
# @api public
|
|
154
158
|
def to_ast(meta: true)
|
|
155
|
-
[:nominal, [primitive,
|
|
159
|
+
[:nominal, [primitive, namespace_ast, meta_ast(meta)]]
|
|
156
160
|
end
|
|
157
161
|
|
|
158
162
|
# Return self. Nominal types are lax by definition
|
|
@@ -168,6 +172,26 @@ module Dry
|
|
|
168
172
|
#
|
|
169
173
|
# @api public
|
|
170
174
|
def to_proc = ALWAYS
|
|
175
|
+
|
|
176
|
+
private
|
|
177
|
+
|
|
178
|
+
# @api private
|
|
179
|
+
def namespace_ast
|
|
180
|
+
if @namespace
|
|
181
|
+
{namespace: @namespace}
|
|
182
|
+
else
|
|
183
|
+
EMPTY_HASH
|
|
184
|
+
end
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
# @api private
|
|
188
|
+
def meta_ast(meta)
|
|
189
|
+
if meta
|
|
190
|
+
self.meta
|
|
191
|
+
else
|
|
192
|
+
EMPTY_HASH
|
|
193
|
+
end
|
|
194
|
+
end
|
|
171
195
|
end
|
|
172
196
|
|
|
173
197
|
extend ::Dry::Core::Deprecations[:"dry-types"]
|
data/lib/dry/types/options.rb
CHANGED
data/lib/dry/types/params.rb
CHANGED
|
@@ -4,63 +4,34 @@ require "dry/types/coercions/params"
|
|
|
4
4
|
|
|
5
5
|
module Dry
|
|
6
6
|
module Types
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
register("params.false") do
|
|
28
|
-
self["nominal.false"].constructor(Coercions::Params.method(:to_false))
|
|
7
|
+
options = {namespace: "params"}
|
|
8
|
+
|
|
9
|
+
{
|
|
10
|
+
"nil" => :to_nil,
|
|
11
|
+
"date" => :to_date,
|
|
12
|
+
"date_time" => :to_date_time,
|
|
13
|
+
"time" => :to_time,
|
|
14
|
+
"true" => :to_true,
|
|
15
|
+
"false" => :to_false,
|
|
16
|
+
"integer" => :to_int,
|
|
17
|
+
"float" => :to_float,
|
|
18
|
+
"decimal" => :to_decimal,
|
|
19
|
+
"array" => :to_ary,
|
|
20
|
+
"hash" => :to_hash,
|
|
21
|
+
"symbol" => :to_symbol
|
|
22
|
+
}.each do |name, method|
|
|
23
|
+
register("params.#{name}") do
|
|
24
|
+
self["nominal.#{name}"].with(**options).constructor(Coercions::Params.method(method))
|
|
25
|
+
end
|
|
29
26
|
end
|
|
30
27
|
|
|
31
28
|
register("params.bool") do
|
|
32
29
|
self["params.true"] | self["params.false"]
|
|
33
30
|
end
|
|
34
31
|
|
|
35
|
-
register("params.
|
|
36
|
-
self["nominal.integer"].constructor(Coercions::Params.method(:to_int))
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
register("params.float") do
|
|
40
|
-
self["nominal.float"].constructor(Coercions::Params.method(:to_float))
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
register("params.decimal") do
|
|
44
|
-
self["nominal.decimal"].constructor(Coercions::Params.method(:to_decimal))
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
register("params.array") do
|
|
48
|
-
self["nominal.array"].constructor(Coercions::Params.method(:to_ary))
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
register("params.hash") do
|
|
52
|
-
self["nominal.hash"].constructor(Coercions::Params.method(:to_hash))
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
register("params.symbol") do
|
|
56
|
-
self["nominal.symbol"].constructor(Coercions::Params.method(:to_symbol))
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
register("params.string", self["string"])
|
|
32
|
+
register("params.string", self["string"].with(**options))
|
|
60
33
|
|
|
61
34
|
COERCIBLE.each_key do |name|
|
|
62
|
-
next if name.equal?(:string)
|
|
63
|
-
|
|
64
35
|
register("optional.params.#{name}", self["params.nil"] | self["params.#{name}"])
|
|
65
36
|
end
|
|
66
37
|
end
|
|
@@ -19,10 +19,7 @@ module Dry
|
|
|
19
19
|
end
|
|
20
20
|
|
|
21
21
|
# @api private
|
|
22
|
-
def visit_nominal(node)
|
|
23
|
-
type, _ = node
|
|
24
|
-
type
|
|
25
|
-
end
|
|
22
|
+
def visit_nominal(node) = node[0]
|
|
26
23
|
|
|
27
24
|
# @api private
|
|
28
25
|
def visit_hash(_) = ::Hash
|
|
@@ -35,16 +32,10 @@ module Dry
|
|
|
35
32
|
def visit_lax(node) = visit(node)
|
|
36
33
|
|
|
37
34
|
# @api private
|
|
38
|
-
def visit_constructor(node)
|
|
39
|
-
other, * = node
|
|
40
|
-
visit(other)
|
|
41
|
-
end
|
|
35
|
+
def visit_constructor(node) = visit(node[0])
|
|
42
36
|
|
|
43
37
|
# @api private
|
|
44
|
-
def visit_enum(node)
|
|
45
|
-
other, * = node
|
|
46
|
-
visit(other)
|
|
47
|
-
end
|
|
38
|
+
def visit_enum(node) = visit(node[0])
|
|
48
39
|
|
|
49
40
|
# @api private
|
|
50
41
|
def visit_sum(node)
|
|
@@ -54,10 +45,7 @@ module Dry
|
|
|
54
45
|
end
|
|
55
46
|
|
|
56
47
|
# @api private
|
|
57
|
-
def visit_constrained(node)
|
|
58
|
-
other, * = node
|
|
59
|
-
visit(other)
|
|
60
|
-
end
|
|
48
|
+
def visit_constrained(node) = visit(node[0])
|
|
61
49
|
|
|
62
50
|
# @api private
|
|
63
51
|
def visit_any(_) = ::Object
|
data/lib/dry/types/printer.rb
CHANGED
|
@@ -105,6 +105,22 @@ module Dry
|
|
|
105
105
|
@composition_printers[klass].visit(composition, &)
|
|
106
106
|
end
|
|
107
107
|
|
|
108
|
+
def visit_sum_constructors(sum)
|
|
109
|
+
visit_sum_constructor(sum.left) do |left|
|
|
110
|
+
visit_sum_constructor(sum.right) do |right|
|
|
111
|
+
yield "#{left} #{sum.class.operator} #{right}"
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def visit_sum_constructor(type, &)
|
|
117
|
+
if type.is_a?(Dry::Types::Sum)
|
|
118
|
+
visit_sum_constructors(type, &)
|
|
119
|
+
else
|
|
120
|
+
visit(type, &)
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
|
|
108
124
|
def visit_enum(enum)
|
|
109
125
|
visit(enum.type) do |type|
|
|
110
126
|
options = enum.options.dup
|
|
@@ -163,7 +179,7 @@ module Dry
|
|
|
163
179
|
elsif path
|
|
164
180
|
yield "#{path.sub("#{Dir.pwd}/", EMPTY_STRING)}:#{line}"
|
|
165
181
|
else
|
|
166
|
-
match = fn.to_s.match(/\A#<Proc:0x\h+\(&:(?<name>\w+)\)(:? \(lambda\))?>\z/)
|
|
182
|
+
match = fn.to_s.match(/\A#<Proc:0x\h+\(&:(?<name>\w+)\)(:? \(lambda\))?>\z/)
|
|
167
183
|
|
|
168
184
|
if match
|
|
169
185
|
yield ".#{match[:name]}"
|
data/lib/dry/types/schema.rb
CHANGED
|
@@ -148,8 +148,8 @@ module Dry
|
|
|
148
148
|
[
|
|
149
149
|
:schema,
|
|
150
150
|
[keys.map { |key| key.to_ast(meta: meta) },
|
|
151
|
-
options.slice(:key_transform_fn, :type_transform_fn, :strict),
|
|
152
|
-
meta
|
|
151
|
+
options.slice(:key_transform_fn, :type_transform_fn, :strict, :namespace),
|
|
152
|
+
meta_ast(meta)]
|
|
153
153
|
]
|
|
154
154
|
end
|
|
155
155
|
|
|
@@ -167,7 +167,7 @@ module Dry
|
|
|
167
167
|
# @return [Schema]
|
|
168
168
|
#
|
|
169
169
|
# @api public
|
|
170
|
-
def strict(strict = true)
|
|
170
|
+
def strict(strict = true)
|
|
171
171
|
with(strict: strict)
|
|
172
172
|
end
|
|
173
173
|
|
|
@@ -326,10 +326,10 @@ module Dry
|
|
|
326
326
|
if type
|
|
327
327
|
begin
|
|
328
328
|
result[k] = type.call_unsafe(value)
|
|
329
|
-
rescue ConstraintError =>
|
|
330
|
-
raise SchemaError.new(type.name, value,
|
|
331
|
-
rescue CoercionError =>
|
|
332
|
-
raise SchemaError.new(type.name, value,
|
|
329
|
+
rescue ConstraintError => exception
|
|
330
|
+
raise SchemaError.new(type.name, value, exception.result)
|
|
331
|
+
rescue CoercionError => exception
|
|
332
|
+
raise SchemaError.new(type.name, value, exception.message)
|
|
333
333
|
end
|
|
334
334
|
elsif strict?
|
|
335
335
|
raise unexpected_keys(hash.keys)
|