dry-schema 0.3.0 → 0.4.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 +31 -0
- data/config/errors.yml +1 -1
- data/lib/dry/schema.rb +0 -9
- data/lib/dry/schema/config.rb +21 -27
- data/lib/dry/schema/constants.rb +17 -3
- data/lib/dry/schema/dsl.rb +13 -22
- data/lib/dry/schema/extensions/hints/message_set_methods.rb +2 -7
- data/lib/dry/schema/extensions/hints/result_methods.rb +3 -3
- data/lib/dry/schema/extensions/monads.rb +1 -1
- data/lib/dry/schema/macros/hash.rb +0 -1
- data/lib/dry/schema/macros/key.rb +13 -8
- data/lib/dry/schema/macros/optional.rb +5 -0
- data/lib/dry/schema/macros/schema.rb +1 -1
- data/lib/dry/schema/message.rb +3 -8
- data/lib/dry/schema/message_compiler.rb +47 -42
- data/lib/dry/schema/message_compiler/visitor_opts.rb +0 -1
- data/lib/dry/schema/message_set.rb +13 -1
- data/lib/dry/schema/messages.rb +16 -25
- data/lib/dry/schema/messages/abstract.rb +53 -36
- data/lib/dry/schema/messages/i18n.rb +40 -23
- data/lib/dry/schema/messages/namespaced.rb +3 -4
- data/lib/dry/schema/messages/yaml.rb +54 -33
- data/lib/dry/schema/predicate_inferrer.rb +56 -14
- data/lib/dry/schema/processor.rb +59 -40
- data/lib/dry/schema/result.rb +2 -2
- data/lib/dry/schema/rule_applier.rb +5 -4
- data/lib/dry/schema/trace.rb +11 -3
- data/lib/dry/schema/type_registry.rb +2 -2
- data/lib/dry/schema/types.rb +1 -1
- data/lib/dry/schema/value_coercer.rb +5 -3
- data/lib/dry/schema/version.rb +1 -1
- metadata +15 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: af5d9afb30c697c7ff8e028dff66ed3a1e28a8d0ed9c6f03ac4bd0e0ff73a364
|
4
|
+
data.tar.gz: 94c6bb4243dfc12bd478e715e716deb1fd9b278761d1822324ed7b8920b0de55
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cf8a06bf211c79bed5ccfc9e02800e47318535036a47b626c29438cae91e3388c380bd9b8b936391718f88c784318f9ef5e88d41a19d06240d9773d2ee7b8270
|
7
|
+
data.tar.gz: 7eaa15a99a94bdcd301fed7d636879a0ef7241d7cf5721bd87ef053c8684ece4b65a0a6aa6fb2f10d7d0947bb66b27548f575749b83190ea2db3bab04f4f08d2
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,34 @@
|
|
1
|
+
# 0.4.0 2019-03-26
|
2
|
+
|
3
|
+
### Added
|
4
|
+
|
5
|
+
* Schemas are now compatible with procs via `#to_proc` (issue #53) (solnic)
|
6
|
+
* Support for configuring `top_namespace` for localized messages (solnic)
|
7
|
+
* Support for configuring more than one load path for localized messages (solnic)
|
8
|
+
* Support for inferring predicates from arbitrary types (issue #101) (solnic)
|
9
|
+
|
10
|
+
### Fixed
|
11
|
+
|
12
|
+
* Handling of messages for `optional` keys without value rules works correctly (issue #87) (solnic)
|
13
|
+
* Message structure for `optional` keys with an array of hashes no longer duplicates keys (issue #89) (solnic)
|
14
|
+
* Inferring `:date_time?` predicate works correctly with `DateTime` types (issue #97) (solnic)
|
15
|
+
|
16
|
+
### Changed
|
17
|
+
|
18
|
+
* [BREAKING] Updated to work with `dry-types 0.15.0` (flash-gordon)
|
19
|
+
* [BREAKING] `Result#{errors,messages,hints}` returns `MessageSet` object now which is an enumerable coercible to a hash (solnic)
|
20
|
+
* [BREAKING] `Messages` backend classes no longer use global configuration (solnic)
|
21
|
+
* [BREAKING] Passing a non-symbol key name in the DSL will raise `ArgumentError` (issue #29) (solnic)
|
22
|
+
* [BREAKING] Configuration for message backends is now nested under `messages` key with following settings:
|
23
|
+
* `messages.backend` - previously `messages`
|
24
|
+
* `messages.load_paths` - previously `messages_path`
|
25
|
+
* `messages.namespace` - previously `namespace`
|
26
|
+
* `messages.top_namespace` - **new setting** see above
|
27
|
+
* [BREAKING] `Messages::I18n` uses `I18.store_translations` instead of messing with `I18n.load_path` (solnic)
|
28
|
+
* Schemas (`Params` and `JSON`) have nicer inspect (solnic)
|
29
|
+
|
30
|
+
[Compare v0.3.0...v0.4.0](https://github.com/dry-rb/dry-schema/compare/v0.3.0...v0.4.0)
|
31
|
+
|
1
32
|
# 0.3.0 2018-03-04
|
2
33
|
|
3
34
|
### Fixed
|
data/config/errors.yml
CHANGED
data/lib/dry/schema.rb
CHANGED
@@ -38,15 +38,6 @@ module Dry
|
|
38
38
|
def self.JSON(**options, &block)
|
39
39
|
define(**options, processor_type: JSON, &block)
|
40
40
|
end
|
41
|
-
|
42
|
-
# Return configured paths to message files
|
43
|
-
#
|
44
|
-
# @return [Array<String>]
|
45
|
-
#
|
46
|
-
# @api public
|
47
|
-
def self.messages_paths
|
48
|
-
Messages::Abstract.config.paths
|
49
|
-
end
|
50
41
|
end
|
51
42
|
end
|
52
43
|
|
data/lib/dry/schema/config.rb
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require '
|
3
|
+
require 'dry/equalizer'
|
4
4
|
require 'dry/configurable'
|
5
5
|
|
6
|
+
require 'dry/schema/constants'
|
6
7
|
require 'dry/schema/predicate_registry'
|
7
8
|
|
8
9
|
module Dry
|
@@ -12,42 +13,35 @@ module Dry
|
|
12
13
|
# @see DSL#configure
|
13
14
|
#
|
14
15
|
# @api public
|
15
|
-
class Config
|
16
|
-
|
16
|
+
class Config
|
17
|
+
include Dry::Configurable
|
18
|
+
include Dry::Equalizer(:predicates, :messages)
|
17
19
|
|
18
|
-
setting
|
19
|
-
setting :messages, :yaml
|
20
|
-
setting :messages_file
|
21
|
-
setting :namespace
|
22
|
-
setting :rules, {}
|
20
|
+
setting(:predicates, Schema::PredicateRegistry.new)
|
23
21
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
22
|
+
setting(:messages) do
|
23
|
+
setting(:backend, :yaml)
|
24
|
+
setting(:namespace)
|
25
|
+
setting(:load_paths, Set[DEFAULT_MESSAGES_PATH], &:dup)
|
26
|
+
setting(:top_namespace, DEFAULT_MESSAGES_ROOT)
|
29
27
|
end
|
30
28
|
|
31
|
-
#
|
29
|
+
# Return configured predicate registry
|
32
30
|
#
|
33
|
-
# @return [
|
31
|
+
# @return [Schema::PredicateRegistry]
|
34
32
|
#
|
35
|
-
# @api
|
36
|
-
def
|
37
|
-
|
33
|
+
# @api public
|
34
|
+
def predicates
|
35
|
+
config.predicates
|
38
36
|
end
|
39
37
|
|
40
|
-
#
|
41
|
-
#
|
42
|
-
# This method is used by `DSL#configure`
|
38
|
+
# Return configuration for message backend
|
43
39
|
#
|
44
|
-
# @return [Config]
|
40
|
+
# @return [Dry::Configurable::Config]
|
45
41
|
#
|
46
|
-
# @api
|
47
|
-
def
|
48
|
-
|
49
|
-
values.freeze
|
50
|
-
freeze
|
42
|
+
# @api public
|
43
|
+
def messages
|
44
|
+
config.messages
|
51
45
|
end
|
52
46
|
end
|
53
47
|
end
|
data/lib/dry/schema/constants.rb
CHANGED
@@ -1,15 +1,29 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'pathname'
|
3
4
|
require 'dry/core/constants'
|
4
5
|
|
5
6
|
module Dry
|
6
7
|
module Schema
|
7
8
|
include Core::Constants
|
8
9
|
|
9
|
-
|
10
|
-
MissingMessageError = Class.new(StandardError)
|
11
|
-
|
10
|
+
LIST_SEPARATOR = ', '
|
12
11
|
QUESTION_MARK = '?'
|
13
12
|
DOT = '.'
|
13
|
+
|
14
|
+
DEFAULT_MESSAGES_PATH = Pathname(__dir__).join('../../../config/errors.yml').realpath.freeze
|
15
|
+
DEFAULT_MESSAGES_ROOT = 'dry_schema'
|
16
|
+
|
17
|
+
InvalidSchemaError = Class.new(StandardError)
|
18
|
+
|
19
|
+
MissingMessageError = Class.new(StandardError) do
|
20
|
+
# @api private
|
21
|
+
def initialize(path)
|
22
|
+
*rest, rule = path
|
23
|
+
super(<<~STR)
|
24
|
+
Message template for #{rule.inspect} under #{rest.join(DOT).inspect} was not found
|
25
|
+
STR
|
26
|
+
end
|
27
|
+
end
|
14
28
|
end
|
15
29
|
end
|
data/lib/dry/schema/dsl.rb
CHANGED
@@ -103,7 +103,7 @@ module Dry
|
|
103
103
|
# @example
|
104
104
|
# Dry::Schema.define do
|
105
105
|
# configure do |config|
|
106
|
-
# config.messages = :i18n
|
106
|
+
# config.messages.backend = :i18n
|
107
107
|
# end
|
108
108
|
# end
|
109
109
|
#
|
@@ -162,6 +162,8 @@ module Dry
|
|
162
162
|
#
|
163
163
|
# @api public
|
164
164
|
def key(name, macro:, &block)
|
165
|
+
raise ArgumentError, "Key +#{name}+ is not a symbol" unless name.is_a?(::Symbol)
|
166
|
+
|
165
167
|
set_type(name, Types::Any)
|
166
168
|
|
167
169
|
macro = macro.new(
|
@@ -214,7 +216,11 @@ module Dry
|
|
214
216
|
#
|
215
217
|
# @api private
|
216
218
|
def type_schema
|
217
|
-
|
219
|
+
if parent
|
220
|
+
parent.type_schema.schema(types)
|
221
|
+
else
|
222
|
+
type_registry['hash'].schema(types).safe
|
223
|
+
end
|
218
224
|
end
|
219
225
|
|
220
226
|
# Return a new DSL instance using the same processor type
|
@@ -236,18 +242,11 @@ module Dry
|
|
236
242
|
# @api private
|
237
243
|
def set_type(name, spec)
|
238
244
|
type = resolve_type(spec)
|
239
|
-
meta = {
|
245
|
+
meta = { required: false, maybe: type.optional? }
|
240
246
|
|
241
247
|
types[name] = type.meta(meta)
|
242
248
|
end
|
243
249
|
|
244
|
-
# Check if the given type is a maybe sum
|
245
|
-
#
|
246
|
-
# @api private
|
247
|
-
def maybe?(type)
|
248
|
-
type.is_a?(Dry::Types::Sum) && type.left.primitive.equal?(NilClass)
|
249
|
-
end
|
250
|
-
|
251
250
|
protected
|
252
251
|
|
253
252
|
# Build a rule applier
|
@@ -265,16 +264,14 @@ module Dry
|
|
265
264
|
#
|
266
265
|
# @api protected
|
267
266
|
def rules
|
268
|
-
parent_rules.merge(macros.map { |m| [m.name, m.to_rule] }.to_h)
|
267
|
+
parent_rules.merge(macros.map { |m| [m.name, m.to_rule] }.to_h.compact)
|
269
268
|
end
|
270
269
|
|
271
270
|
# Build a key map from defined types
|
272
271
|
#
|
273
272
|
# @api protected
|
274
273
|
def key_map(types = self.types)
|
275
|
-
keys = types.
|
276
|
-
arr << key_spec(key_name, types[key_name])
|
277
|
-
}
|
274
|
+
keys = types.map { |key, type| key_spec(key, type) }
|
278
275
|
km = KeyMap.new(keys)
|
279
276
|
|
280
277
|
if key_map_type
|
@@ -338,8 +335,8 @@ module Dry
|
|
338
335
|
#
|
339
336
|
# @api private
|
340
337
|
def key_spec(name, type)
|
341
|
-
if type.respond_to?(:
|
342
|
-
{ name => key_map(type.
|
338
|
+
if type.respond_to?(:keys)
|
339
|
+
{ name => key_map(type.name_key_map) }
|
343
340
|
elsif type.respond_to?(:member)
|
344
341
|
kv = key_spec(name, type.member)
|
345
342
|
kv.equal?(name) ? name : kv.flatten(1)
|
@@ -369,12 +366,6 @@ module Dry
|
|
369
366
|
parent&.rules || EMPTY_HASH
|
370
367
|
end
|
371
368
|
|
372
|
-
# @api private
|
373
|
-
def parent_types
|
374
|
-
# TODO: this is awful, it'd be nice if we had `Dry::Types::Hash::Schema#merge`
|
375
|
-
parent&.type_schema&.member_types || EMPTY_HASH
|
376
|
-
end
|
377
|
-
|
378
369
|
# @api private
|
379
370
|
def parent_key_map
|
380
371
|
parent&.key_map || EMPTY_ARRAY
|
@@ -11,19 +11,14 @@ module Dry
|
|
11
11
|
def initialize(messages, options = EMPTY_HASH)
|
12
12
|
super
|
13
13
|
@hints = messages.select(&:hint?)
|
14
|
+
@failures = options.fetch(:failures, true)
|
14
15
|
end
|
15
16
|
|
16
17
|
# @api public
|
17
18
|
def to_h
|
18
|
-
failures
|
19
|
+
failures ? messages_map : messages_map(hints)
|
19
20
|
end
|
20
21
|
alias_method :to_hash, :to_h
|
21
|
-
alias_method :dump, :to_h
|
22
|
-
|
23
|
-
# @api private
|
24
|
-
def failures?
|
25
|
-
options[:failures].equal?(true)
|
26
|
-
end
|
27
22
|
end
|
28
23
|
end
|
29
24
|
end
|
@@ -9,7 +9,7 @@ module Dry
|
|
9
9
|
#
|
10
10
|
# @api public
|
11
11
|
def errors(options = EMPTY_HASH)
|
12
|
-
message_set(options.merge(hints: false))
|
12
|
+
message_set(options.merge(hints: false))
|
13
13
|
end
|
14
14
|
|
15
15
|
# Get all messages including hints
|
@@ -20,7 +20,7 @@ module Dry
|
|
20
20
|
#
|
21
21
|
# @api public
|
22
22
|
def messages(options = EMPTY_HASH)
|
23
|
-
message_set(options)
|
23
|
+
message_set(options)
|
24
24
|
end
|
25
25
|
|
26
26
|
# Get hints exclusively without errors
|
@@ -31,7 +31,7 @@ module Dry
|
|
31
31
|
#
|
32
32
|
# @api public
|
33
33
|
def hints(options = EMPTY_HASH)
|
34
|
-
message_set(options.merge(failures: false))
|
34
|
+
message_set(options.merge(failures: false))
|
35
35
|
end
|
36
36
|
end
|
37
37
|
end
|
@@ -14,8 +14,18 @@ module Dry
|
|
14
14
|
#
|
15
15
|
# @api public
|
16
16
|
class Key < DSL
|
17
|
+
# @!attribute [r] filter_schema
|
18
|
+
# @return [Schema::DSL]
|
19
|
+
# @api private
|
17
20
|
option :filter_schema, optional: true, default: proc { schema_dsl&.new }
|
18
21
|
|
22
|
+
# @!attribute [r] predicate_inferrer
|
23
|
+
# @return [PredicateInferrer]
|
24
|
+
# @api private
|
25
|
+
option :predicate_inferrer, default: proc {
|
26
|
+
PredicateInferrer.new(compiler.predicates)
|
27
|
+
}
|
28
|
+
|
19
29
|
# Specify predicates that should be used to filter out values
|
20
30
|
# before coercion is applied
|
21
31
|
#
|
@@ -116,16 +126,11 @@ module Dry
|
|
116
126
|
|
117
127
|
if type_spec
|
118
128
|
type(nullable && !type_spec.is_a?(::Array) ? [:nil, type_spec] : type_spec)
|
119
|
-
type_predicates = PredicateInferrer[schema_dsl.types[name]]
|
120
129
|
|
121
|
-
|
122
|
-
type_predicates.each do |pred|
|
123
|
-
unless compiler.supports?(pred)
|
124
|
-
raise ArgumentError, "Predicate +#{pred.inspect}+ inferred from #{type_spec.inspect} type spec is not supported"
|
125
|
-
end
|
126
|
-
end
|
130
|
+
type_predicates = predicate_inferrer[schema_dsl.types[name]]
|
127
131
|
|
128
|
-
|
132
|
+
unless predicates.include?(type_predicates)
|
133
|
+
if type_predicates.is_a?(::Array) && type_predicates.size.equal?(1)
|
129
134
|
predicates.unshift(type_predicates[0])
|
130
135
|
else
|
131
136
|
predicates.unshift(type_predicates)
|
data/lib/dry/schema/message.rb
CHANGED
@@ -11,7 +11,7 @@ module Dry
|
|
11
11
|
class Message
|
12
12
|
include Dry::Equalizer(:predicate, :path, :text, :options)
|
13
13
|
|
14
|
-
attr_reader :predicate, :path, :text, :
|
14
|
+
attr_reader :predicate, :path, :text, :args, :options
|
15
15
|
|
16
16
|
# A message sub-type used by OR operations
|
17
17
|
#
|
@@ -43,7 +43,7 @@ module Dry
|
|
43
43
|
#
|
44
44
|
# @api public
|
45
45
|
def to_s
|
46
|
-
uniq.join(" #{messages[:or]
|
46
|
+
uniq.join(" #{messages[:or]} ")
|
47
47
|
end
|
48
48
|
|
49
49
|
# @api private
|
@@ -67,15 +67,10 @@ module Dry
|
|
67
67
|
# @api private
|
68
68
|
def initialize(predicate, path, text, options)
|
69
69
|
@predicate = predicate
|
70
|
-
@path = path
|
70
|
+
@path = path
|
71
71
|
@text = text
|
72
72
|
@options = options
|
73
|
-
@rule = options[:rule]
|
74
73
|
@args = options[:args] || EMPTY_ARRAY
|
75
|
-
|
76
|
-
if predicate == :key?
|
77
|
-
@path << rule
|
78
|
-
end
|
79
74
|
end
|
80
75
|
|
81
76
|
# Return a string representation of the message
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'dry/initializer'
|
4
|
+
|
3
5
|
require 'dry/schema/constants'
|
4
6
|
require 'dry/schema/message'
|
5
7
|
require 'dry/schema/message_set'
|
@@ -11,28 +13,43 @@ module Dry
|
|
11
13
|
#
|
12
14
|
# @api private
|
13
15
|
class MessageCompiler
|
14
|
-
|
16
|
+
extend Dry::Initializer
|
17
|
+
|
18
|
+
resolve_key_predicate = proc { |node, opts|
|
19
|
+
*arg_vals, val = node.map(&:last)
|
20
|
+
[[*opts.path, arg_vals[0]], arg_vals[1..arg_vals.size - 1], val]
|
21
|
+
}
|
22
|
+
|
23
|
+
resolve_predicate = proc { |node, opts|
|
24
|
+
[Array(opts.path), *node.map(&:last)]
|
25
|
+
}
|
26
|
+
|
27
|
+
DEFAULT_PREDICATE_RESOLVERS = Hash
|
28
|
+
.new(resolve_predicate).update(key?: resolve_key_predicate).freeze
|
15
29
|
|
16
30
|
EMPTY_OPTS = VisitorOpts.new
|
17
|
-
LIST_SEPARATOR = ', '
|
18
31
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
32
|
+
param :messages
|
33
|
+
|
34
|
+
option :full, default: -> { false }
|
35
|
+
option :locale, default: -> { :en }
|
36
|
+
option :predicate_resolvers, default: -> { DEFAULT_PREDICATE_RESOLVERS }
|
37
|
+
|
38
|
+
attr_reader :options
|
39
|
+
|
40
|
+
attr_reader :default_lookup_options
|
27
41
|
|
28
42
|
# @api private
|
29
|
-
def
|
30
|
-
|
43
|
+
def initialize(messages, options = EMPTY_HASH)
|
44
|
+
super
|
45
|
+
@options = options
|
46
|
+
@default_lookup_options = options[:locale] ? { locale: locale } : EMPTY_HASH
|
31
47
|
end
|
32
48
|
|
33
49
|
# @api private
|
34
50
|
def with(new_options)
|
35
51
|
return self if new_options.empty?
|
52
|
+
|
36
53
|
self.class.new(messages, options.merge(new_options))
|
37
54
|
end
|
38
55
|
|
@@ -56,7 +73,7 @@ module Dry
|
|
56
73
|
end
|
57
74
|
|
58
75
|
# @api private
|
59
|
-
def visit_hint(
|
76
|
+
def visit_hint(*)
|
60
77
|
nil
|
61
78
|
end
|
62
79
|
|
@@ -81,7 +98,7 @@ module Dry
|
|
81
98
|
left, right = node.map { |n| visit(n, opts) }
|
82
99
|
|
83
100
|
if [left, right].flatten.map(&:path).uniq.size == 1
|
84
|
-
Message::Or.new(left, right,
|
101
|
+
Message::Or.new(left, right, proc { |k| messages.translate(k, default_lookup_options) })
|
85
102
|
elsif right.is_a?(Array)
|
86
103
|
right
|
87
104
|
else
|
@@ -97,33 +114,23 @@ module Dry
|
|
97
114
|
|
98
115
|
# @api private
|
99
116
|
def visit_predicate(node, opts)
|
100
|
-
base_opts = opts.dup
|
101
117
|
predicate, args = node
|
102
118
|
|
103
|
-
*arg_vals, val = args.map(&:last)
|
104
119
|
tokens = message_tokens(args)
|
120
|
+
path, *arg_vals, input = predicate_resolvers[predicate].(args, opts)
|
105
121
|
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
msg_opts = options.update(tokens)
|
110
|
-
|
111
|
-
rule = msg_opts[:rule]
|
112
|
-
path = msg_opts[:path]
|
113
|
-
|
114
|
-
template = messages[rule] || messages[predicate, msg_opts]
|
122
|
+
options = opts.dup.update(
|
123
|
+
path: path.last, **tokens, **lookup_options(arg_vals: arg_vals, input: input)
|
124
|
+
).to_h
|
115
125
|
|
116
|
-
|
117
|
-
raise MissingMessageError, "message for #{predicate} was not found"
|
118
|
-
end
|
126
|
+
template = messages[predicate, options] || raise(MissingMessageError, path)
|
119
127
|
|
120
|
-
text = message_text(
|
128
|
+
text = message_text(template, tokens, options)
|
121
129
|
|
122
130
|
message_type(options)[
|
123
131
|
predicate, path, text,
|
124
132
|
args: arg_vals,
|
125
|
-
input: input
|
126
|
-
rule: rule || msg_opts[:name]
|
133
|
+
input: input
|
127
134
|
]
|
128
135
|
end
|
129
136
|
|
@@ -156,28 +163,26 @@ module Dry
|
|
156
163
|
end
|
157
164
|
|
158
165
|
# @api private
|
159
|
-
def lookup_options(arg_vals
|
166
|
+
def lookup_options(arg_vals:, input:)
|
160
167
|
default_lookup_options.merge(
|
161
168
|
arg_type: arg_vals.size == 1 && arg_vals[0].class,
|
162
|
-
val_type: input.class
|
169
|
+
val_type: input.equal?(Undefined) ? NilClass : input.class
|
163
170
|
)
|
164
171
|
end
|
165
172
|
|
166
173
|
# @api private
|
167
|
-
def message_text(
|
174
|
+
def message_text(template, tokens, options)
|
168
175
|
text = template[template.data(tokens)]
|
169
176
|
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
text
|
175
|
-
end
|
177
|
+
return text unless full
|
178
|
+
|
179
|
+
rule = options[:path]
|
180
|
+
"#{messages.rule(rule, options) || rule} #{text}"
|
176
181
|
end
|
177
182
|
|
178
183
|
# @api private
|
179
184
|
def message_tokens(args)
|
180
|
-
args.each_with_object({})
|
185
|
+
args.each_with_object({}) do |arg, hash|
|
181
186
|
case arg[1]
|
182
187
|
when Array
|
183
188
|
hash[arg[0]] = arg[1].join(LIST_SEPARATOR)
|
@@ -187,7 +192,7 @@ module Dry
|
|
187
192
|
else
|
188
193
|
hash[arg[0]] = arg[1]
|
189
194
|
end
|
190
|
-
|
195
|
+
end
|
191
196
|
end
|
192
197
|
end
|
193
198
|
end
|