dry-validation 0.12.0 → 1.6.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.
Files changed (204) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +696 -239
  3. data/LICENSE +1 -1
  4. data/README.md +15 -12
  5. data/config/errors.yml +3 -88
  6. data/dry-validation.gemspec +31 -17
  7. data/lib/dry-validation.rb +3 -1
  8. data/lib/dry/validation.rb +45 -28
  9. data/lib/dry/validation/config.rb +24 -0
  10. data/lib/dry/validation/constants.rb +43 -0
  11. data/lib/dry/validation/contract.rb +171 -0
  12. data/lib/dry/validation/contract/class_interface.rb +230 -0
  13. data/lib/dry/validation/evaluator.rb +224 -0
  14. data/lib/dry/validation/extensions/hints.rb +67 -0
  15. data/lib/dry/validation/extensions/monads.rb +24 -8
  16. data/lib/dry/validation/extensions/predicates_as_macros.rb +75 -0
  17. data/lib/dry/validation/failures.rb +70 -0
  18. data/lib/dry/validation/function.rb +44 -0
  19. data/lib/dry/validation/macro.rb +38 -0
  20. data/lib/dry/validation/macros.rb +104 -0
  21. data/lib/dry/validation/message.rb +80 -80
  22. data/lib/dry/validation/message_set.rb +80 -105
  23. data/lib/dry/validation/messages/resolver.rb +131 -0
  24. data/lib/dry/validation/result.rb +183 -41
  25. data/lib/dry/validation/rule.rb +135 -0
  26. data/lib/dry/validation/schema_ext.rb +19 -0
  27. data/lib/dry/validation/values.rb +104 -0
  28. data/lib/dry/validation/version.rb +3 -1
  29. metadata +47 -336
  30. data/.codeclimate.yml +0 -17
  31. data/.gitignore +0 -9
  32. data/.rspec +0 -3
  33. data/.travis.yml +0 -26
  34. data/CONTRIBUTING.md +0 -31
  35. data/Gemfile +0 -33
  36. data/Rakefile +0 -22
  37. data/benchmarks/benchmark_form_invalid.rb +0 -64
  38. data/benchmarks/benchmark_form_valid.rb +0 -64
  39. data/benchmarks/benchmark_schema_invalid_huge.rb +0 -52
  40. data/benchmarks/profile_schema_call_invalid.rb +0 -20
  41. data/benchmarks/profile_schema_call_valid.rb +0 -20
  42. data/benchmarks/profile_schema_definition.rb +0 -14
  43. data/benchmarks/profile_schema_huge_invalid.rb +0 -30
  44. data/benchmarks/profile_schema_messages_invalid.rb +0 -20
  45. data/benchmarks/suite.rb +0 -5
  46. data/examples/basic.rb +0 -15
  47. data/examples/each.rb +0 -14
  48. data/examples/json.rb +0 -12
  49. data/examples/multiple.rb +0 -27
  50. data/examples/nested.rb +0 -22
  51. data/examples/params.rb +0 -11
  52. data/lib/dry/validation/compat/form.rb +0 -67
  53. data/lib/dry/validation/deprecations.rb +0 -24
  54. data/lib/dry/validation/executor.rb +0 -91
  55. data/lib/dry/validation/extensions.rb +0 -7
  56. data/lib/dry/validation/extensions/struct.rb +0 -32
  57. data/lib/dry/validation/input_processor_compiler.rb +0 -135
  58. data/lib/dry/validation/input_processor_compiler/json.rb +0 -45
  59. data/lib/dry/validation/input_processor_compiler/params.rb +0 -49
  60. data/lib/dry/validation/input_processor_compiler/sanitizer.rb +0 -47
  61. data/lib/dry/validation/message_compiler.rb +0 -192
  62. data/lib/dry/validation/message_compiler/visitor_opts.rb +0 -37
  63. data/lib/dry/validation/messages.rb +0 -14
  64. data/lib/dry/validation/messages/abstract.rb +0 -112
  65. data/lib/dry/validation/messages/i18n.rb +0 -35
  66. data/lib/dry/validation/messages/namespaced.rb +0 -32
  67. data/lib/dry/validation/messages/yaml.rb +0 -54
  68. data/lib/dry/validation/predicate_registry.rb +0 -115
  69. data/lib/dry/validation/schema.rb +0 -126
  70. data/lib/dry/validation/schema/check.rb +0 -37
  71. data/lib/dry/validation/schema/class_interface.rb +0 -189
  72. data/lib/dry/validation/schema/deprecated.rb +0 -30
  73. data/lib/dry/validation/schema/dsl.rb +0 -118
  74. data/lib/dry/validation/schema/form.rb +0 -9
  75. data/lib/dry/validation/schema/json.rb +0 -21
  76. data/lib/dry/validation/schema/key.rb +0 -71
  77. data/lib/dry/validation/schema/params.rb +0 -22
  78. data/lib/dry/validation/schema/rule.rb +0 -202
  79. data/lib/dry/validation/schema/value.rb +0 -211
  80. data/lib/dry/validation/schema_compiler.rb +0 -81
  81. data/lib/dry/validation/type_specs.rb +0 -70
  82. data/spec/extensions/monads/result_spec.rb +0 -40
  83. data/spec/extensions/struct/schema_spec.rb +0 -32
  84. data/spec/fixtures/locales/en.yml +0 -6
  85. data/spec/fixtures/locales/pl.yml +0 -18
  86. data/spec/integration/custom_error_messages_spec.rb +0 -48
  87. data/spec/integration/custom_predicates_spec.rb +0 -228
  88. data/spec/integration/hints_spec.rb +0 -170
  89. data/spec/integration/injecting_rules_spec.rb +0 -30
  90. data/spec/integration/json/defining_base_schema_spec.rb +0 -41
  91. data/spec/integration/localized_error_messages_spec.rb +0 -72
  92. data/spec/integration/message_compiler_spec.rb +0 -405
  93. data/spec/integration/messages/i18n_spec.rb +0 -94
  94. data/spec/integration/optional_keys_spec.rb +0 -28
  95. data/spec/integration/params/predicates/array_spec.rb +0 -287
  96. data/spec/integration/params/predicates/empty_spec.rb +0 -263
  97. data/spec/integration/params/predicates/eql_spec.rb +0 -327
  98. data/spec/integration/params/predicates/even_spec.rb +0 -455
  99. data/spec/integration/params/predicates/excluded_from_spec.rb +0 -455
  100. data/spec/integration/params/predicates/excludes_spec.rb +0 -391
  101. data/spec/integration/params/predicates/false_spec.rb +0 -455
  102. data/spec/integration/params/predicates/filled_spec.rb +0 -467
  103. data/spec/integration/params/predicates/format_spec.rb +0 -454
  104. data/spec/integration/params/predicates/gt_spec.rb +0 -519
  105. data/spec/integration/params/predicates/gteq_spec.rb +0 -519
  106. data/spec/integration/params/predicates/included_in_spec.rb +0 -455
  107. data/spec/integration/params/predicates/includes_spec.rb +0 -391
  108. data/spec/integration/params/predicates/key_spec.rb +0 -67
  109. data/spec/integration/params/predicates/lt_spec.rb +0 -519
  110. data/spec/integration/params/predicates/lteq_spec.rb +0 -519
  111. data/spec/integration/params/predicates/max_size_spec.rb +0 -391
  112. data/spec/integration/params/predicates/min_size_spec.rb +0 -391
  113. data/spec/integration/params/predicates/none_spec.rb +0 -265
  114. data/spec/integration/params/predicates/not_eql_spec.rb +0 -327
  115. data/spec/integration/params/predicates/odd_spec.rb +0 -455
  116. data/spec/integration/params/predicates/size/fixed_spec.rb +0 -393
  117. data/spec/integration/params/predicates/size/range_spec.rb +0 -396
  118. data/spec/integration/params/predicates/true_spec.rb +0 -455
  119. data/spec/integration/params/predicates/type_spec.rb +0 -391
  120. data/spec/integration/result_spec.rb +0 -81
  121. data/spec/integration/schema/array_schema_spec.rb +0 -59
  122. data/spec/integration/schema/check_rules_spec.rb +0 -119
  123. data/spec/integration/schema/check_with_nested_el_spec.rb +0 -37
  124. data/spec/integration/schema/check_with_nth_el_spec.rb +0 -25
  125. data/spec/integration/schema/default_settings_spec.rb +0 -11
  126. data/spec/integration/schema/defining_base_schema_spec.rb +0 -41
  127. data/spec/integration/schema/dynamic_predicate_args_spec.rb +0 -43
  128. data/spec/integration/schema/each_with_set_spec.rb +0 -70
  129. data/spec/integration/schema/extending_dsl_spec.rb +0 -27
  130. data/spec/integration/schema/form_spec.rb +0 -236
  131. data/spec/integration/schema/hash_schema_spec.rb +0 -47
  132. data/spec/integration/schema/inheriting_schema_spec.rb +0 -31
  133. data/spec/integration/schema/input_processor_spec.rb +0 -46
  134. data/spec/integration/schema/json/explicit_types_spec.rb +0 -157
  135. data/spec/integration/schema/json_spec.rb +0 -163
  136. data/spec/integration/schema/macros/confirmation_spec.rb +0 -35
  137. data/spec/integration/schema/macros/each_spec.rb +0 -268
  138. data/spec/integration/schema/macros/filled_spec.rb +0 -87
  139. data/spec/integration/schema/macros/input_spec.rb +0 -139
  140. data/spec/integration/schema/macros/maybe_spec.rb +0 -99
  141. data/spec/integration/schema/macros/rule_spec.rb +0 -75
  142. data/spec/integration/schema/macros/value_spec.rb +0 -119
  143. data/spec/integration/schema/macros/when_spec.rb +0 -62
  144. data/spec/integration/schema/nested_schemas_spec.rb +0 -236
  145. data/spec/integration/schema/nested_values_spec.rb +0 -46
  146. data/spec/integration/schema/not_spec.rb +0 -34
  147. data/spec/integration/schema/numbers_spec.rb +0 -19
  148. data/spec/integration/schema/option_with_default_spec.rb +0 -64
  149. data/spec/integration/schema/or_spec.rb +0 -87
  150. data/spec/integration/schema/params/defining_base_schema_spec.rb +0 -41
  151. data/spec/integration/schema/params/explicit_types_spec.rb +0 -195
  152. data/spec/integration/schema/params_spec.rb +0 -234
  153. data/spec/integration/schema/predicate_verification_spec.rb +0 -9
  154. data/spec/integration/schema/predicates/array_spec.rb +0 -295
  155. data/spec/integration/schema/predicates/custom_spec.rb +0 -103
  156. data/spec/integration/schema/predicates/empty_spec.rb +0 -263
  157. data/spec/integration/schema/predicates/eql_spec.rb +0 -327
  158. data/spec/integration/schema/predicates/even_spec.rb +0 -455
  159. data/spec/integration/schema/predicates/excluded_from/array_spec.rb +0 -459
  160. data/spec/integration/schema/predicates/excluded_from/range_spec.rb +0 -459
  161. data/spec/integration/schema/predicates/excludes_spec.rb +0 -391
  162. data/spec/integration/schema/predicates/filled_spec.rb +0 -467
  163. data/spec/integration/schema/predicates/format_spec.rb +0 -455
  164. data/spec/integration/schema/predicates/gt_spec.rb +0 -519
  165. data/spec/integration/schema/predicates/gteq_spec.rb +0 -519
  166. data/spec/integration/schema/predicates/hash_spec.rb +0 -69
  167. data/spec/integration/schema/predicates/included_in/array_spec.rb +0 -459
  168. data/spec/integration/schema/predicates/included_in/range_spec.rb +0 -459
  169. data/spec/integration/schema/predicates/includes_spec.rb +0 -391
  170. data/spec/integration/schema/predicates/key_spec.rb +0 -88
  171. data/spec/integration/schema/predicates/lt_spec.rb +0 -520
  172. data/spec/integration/schema/predicates/lteq_spec.rb +0 -519
  173. data/spec/integration/schema/predicates/max_size_spec.rb +0 -391
  174. data/spec/integration/schema/predicates/min_size_spec.rb +0 -391
  175. data/spec/integration/schema/predicates/none_spec.rb +0 -265
  176. data/spec/integration/schema/predicates/not_eql_spec.rb +0 -391
  177. data/spec/integration/schema/predicates/odd_spec.rb +0 -455
  178. data/spec/integration/schema/predicates/size/fixed_spec.rb +0 -398
  179. data/spec/integration/schema/predicates/size/range_spec.rb +0 -395
  180. data/spec/integration/schema/predicates/type_spec.rb +0 -413
  181. data/spec/integration/schema/reusing_schema_spec.rb +0 -33
  182. data/spec/integration/schema/using_types_spec.rb +0 -135
  183. data/spec/integration/schema/validate_spec.rb +0 -120
  184. data/spec/integration/schema/xor_spec.rb +0 -35
  185. data/spec/integration/schema_builders_spec.rb +0 -17
  186. data/spec/integration/schema_spec.rb +0 -173
  187. data/spec/shared/message_compiler.rb +0 -11
  188. data/spec/shared/predicate_helper.rb +0 -15
  189. data/spec/shared/rule_compiler.rb +0 -8
  190. data/spec/spec_helper.rb +0 -58
  191. data/spec/support/define_struct.rb +0 -25
  192. data/spec/support/matchers.rb +0 -38
  193. data/spec/support/mutant.rb +0 -9
  194. data/spec/support/predicates_integration.rb +0 -7
  195. data/spec/unit/input_processor_compiler/json_spec.rb +0 -283
  196. data/spec/unit/input_processor_compiler/params_spec.rb +0 -328
  197. data/spec/unit/message_compiler/visit_failure_spec.rb +0 -38
  198. data/spec/unit/message_compiler/visit_spec.rb +0 -16
  199. data/spec/unit/message_compiler_spec.rb +0 -7
  200. data/spec/unit/predicate_registry_spec.rb +0 -34
  201. data/spec/unit/schema/key_spec.rb +0 -38
  202. data/spec/unit/schema/rule_spec.rb +0 -42
  203. data/spec/unit/schema/value_spec.rb +0 -131
  204. data/spec/unit/schema_spec.rb +0 -35
@@ -1,45 +0,0 @@
1
- module Dry
2
- module Validation
3
- class InputProcessorCompiler::JSON < InputProcessorCompiler
4
- PREDICATE_MAP = {
5
- default: 'string',
6
- none?: 'json.nil',
7
- bool?: 'bool',
8
- str?: 'string',
9
- int?: 'int',
10
- float?: 'float',
11
- decimal?: 'json.decimal',
12
- date?: 'json.date',
13
- date_time?: 'json.date_time',
14
- time?: 'json.time'
15
- }.freeze
16
-
17
- CONST_MAP = {
18
- NilClass => 'nil',
19
- String => 'string',
20
- Integer => 'int',
21
- Float => 'float',
22
- BigDecimal => 'json.decimal',
23
- Array => 'json.array',
24
- Hash => 'json.hash',
25
- Date => 'json.date',
26
- DateTime => 'json.date_time',
27
- Time => 'json.time',
28
- TrueClass => 'true',
29
- FalseClass => 'false'
30
- }.freeze
31
-
32
- def identifier
33
- :json
34
- end
35
-
36
- def hash_node(schema)
37
- [:json_hash, [schema, {}]]
38
- end
39
-
40
- def array_node(members)
41
- [:json_array, [members, {}]]
42
- end
43
- end
44
- end
45
- end
@@ -1,49 +0,0 @@
1
- module Dry
2
- module Validation
3
- class InputProcessorCompiler::Params < InputProcessorCompiler
4
- PREDICATE_MAP = {
5
- default: 'string',
6
- none?: 'params.nil',
7
- bool?: 'params.bool',
8
- true?: 'params.true',
9
- false?: 'params.false',
10
- str?: 'string',
11
- int?: 'params.integer',
12
- float?: 'params.float',
13
- decimal?: 'params.decimal',
14
- date?: 'params.date',
15
- date_time?: 'params.date_time',
16
- time?: 'params.time',
17
- hash?: 'params.hash',
18
- array?: 'params.array'
19
- }.freeze
20
-
21
- CONST_MAP = {
22
- NilClass => 'params.nil',
23
- String => 'string',
24
- Integer => 'params.integer',
25
- Float => 'params.float',
26
- BigDecimal => 'params.decimal',
27
- Array => 'params.array',
28
- Hash => 'params.hash',
29
- Date => 'params.date',
30
- DateTime => 'params.date_time',
31
- Time => 'params.time',
32
- TrueClass => 'params.true',
33
- FalseClass => 'params.false'
34
- }.freeze
35
-
36
- def identifier
37
- :params
38
- end
39
-
40
- def hash_node(schema)
41
- [:params_hash, [schema, {}]]
42
- end
43
-
44
- def array_node(members)
45
- [:params_array, [members, {}]]
46
- end
47
- end
48
- end
49
- end
@@ -1,47 +0,0 @@
1
- module Dry
2
- module Validation
3
- class InputProcessorCompiler::Sanitizer < InputProcessorCompiler
4
- PREDICATE_MAP = {
5
- default: 'string',
6
- none?: 'nil',
7
- bool?: 'bool',
8
- str?: 'string',
9
- int?: 'int',
10
- float?: 'float',
11
- decimal?: 'decimal',
12
- date?: 'date',
13
- date_time?: 'date_time',
14
- time?: 'time',
15
- hash?: 'hash',
16
- array?: 'array'
17
- }.freeze
18
-
19
- CONST_MAP = {
20
- NilClass => 'nil',
21
- String => 'string',
22
- Integer => 'int',
23
- Float => 'float',
24
- BigDecimal => 'decimal',
25
- Array => 'array',
26
- Hash => 'hash',
27
- Date => 'date',
28
- DateTime => 'date_time',
29
- Time => 'time',
30
- TrueClass => 'true',
31
- FalseClass => 'false'
32
- }.freeze
33
-
34
- def identifier
35
- :sanitizer
36
- end
37
-
38
- def hash_node(schema)
39
- [:hash, [:weak, schema, {}]]
40
- end
41
-
42
- def array_node(members)
43
- [:array, [members, {}]]
44
- end
45
- end
46
- end
47
- end
@@ -1,192 +0,0 @@
1
- require 'dry/validation/message'
2
- require 'dry/validation/message_set'
3
- require 'dry/validation/message_compiler/visitor_opts'
4
-
5
- module Dry
6
- module Validation
7
- class MessageCompiler
8
- attr_reader :messages, :options, :locale, :default_lookup_options
9
-
10
- EMPTY_OPTS = VisitorOpts.new
11
- LIST_SEPARATOR = ', '.freeze
12
-
13
- def initialize(messages, options = {})
14
- @messages = messages
15
- @options = options
16
- @full = @options.fetch(:full, false)
17
- @hints = @options.fetch(:hints, true)
18
- @locale = @options.fetch(:locale, messages.default_locale)
19
- @default_lookup_options = { locale: locale }
20
- end
21
-
22
- def full?
23
- @full
24
- end
25
-
26
- def hints?
27
- @hints
28
- end
29
-
30
- def with(new_options)
31
- return self if new_options.empty?
32
- self.class.new(messages, options.merge(new_options))
33
- end
34
-
35
- def call(ast)
36
- MessageSet[ast.map { |node| visit(node) }, failures: options.fetch(:failures, true)]
37
- end
38
-
39
- def visit(node, *args)
40
- __send__(:"visit_#{node[0]}", node[1], *args)
41
- end
42
-
43
- def visit_failure(node, opts = EMPTY_OPTS)
44
- rule, other = node
45
- visit(other, opts.(rule: rule))
46
- end
47
-
48
- def visit_hint(node, opts = EMPTY_OPTS)
49
- if hints?
50
- visit(node, opts.(message_type: :hint))
51
- end
52
- end
53
-
54
- def visit_each(node, opts = EMPTY_OPTS)
55
- # TODO: we can still generate a hint for elements here!
56
- []
57
- end
58
-
59
- def visit_not(node, opts = EMPTY_OPTS)
60
- visit(node, opts.(not: true))
61
- end
62
-
63
- def visit_check(node, opts = EMPTY_OPTS)
64
- keys, other = node
65
- visit(other, opts.(path: keys.last, check: true))
66
- end
67
-
68
- def visit_rule(node, opts = EMPTY_OPTS)
69
- name, other = node
70
- visit(other, opts.(rule: name))
71
- end
72
-
73
- def visit_schema(node, opts = EMPTY_OPTS)
74
- node.rule_ast.map { |rule| visit(rule, opts) }
75
- end
76
-
77
- def visit_and(node, opts = EMPTY_OPTS)
78
- left, right = node.map { |n| visit(n, opts) }
79
-
80
- if right
81
- [left, right]
82
- else
83
- left
84
- end
85
- end
86
-
87
- def visit_or(node, opts = EMPTY_OPTS)
88
- left, right = node.map { |n| visit(n, opts) }
89
-
90
- if [left, right].flatten.map(&:path).uniq.size == 1
91
- Message::Or.new(left, right, -> k { messages[k, default_lookup_options] })
92
- elsif right.is_a?(Array)
93
- right
94
- else
95
- [left, right]
96
- end
97
- end
98
-
99
- def visit_predicate(node, base_opts = EMPTY_OPTS)
100
- predicate, args = node
101
-
102
- *arg_vals, val = args.map(&:last)
103
- tokens = message_tokens(args)
104
-
105
- input = val != Undefined ? val : nil
106
-
107
- options = base_opts.update(lookup_options(arg_vals: arg_vals, input: input))
108
- msg_opts = options.update(tokens)
109
-
110
- rule = msg_opts[:rule]
111
- path = msg_opts[:path]
112
-
113
- template = messages[rule] || messages[predicate, msg_opts]
114
-
115
- unless template
116
- raise MissingMessageError, "message for #{predicate} was not found"
117
- end
118
-
119
- text = message_text(rule, template, tokens, options)
120
-
121
- message_class = options[:message_type] == :hint ? Hint : Message
122
-
123
- message_class[
124
- predicate, path, text,
125
- args: arg_vals,
126
- input: input,
127
- rule: rule,
128
- check: base_opts[:check]
129
- ]
130
- end
131
-
132
- def visit_key(node, opts = EMPTY_OPTS)
133
- name, other = node
134
- visit(other, opts.(path: name))
135
- end
136
-
137
- def visit_set(node, opts = EMPTY_OPTS)
138
- node.map { |el| visit(el, opts) }
139
- end
140
-
141
- def visit_implication(node, *args)
142
- _, right = node
143
- visit(right, *args)
144
- end
145
-
146
- def visit_xor(node, opts = EMPTY_OPTS)
147
- left, right = node
148
- [visit(left, opts), visit(right, opts)].uniq
149
- end
150
-
151
- def visit_type(node, opts = EMPTY_OPTS)
152
- visit(node.rule.to_ast, opts)
153
- end
154
-
155
- def lookup_options(arg_vals: [], input: nil)
156
- default_lookup_options.merge(
157
- arg_type: arg_vals.size == 1 && arg_vals[0].class,
158
- val_type: input.class
159
- )
160
- end
161
-
162
- def message_text(rule, template, tokens, opts)
163
- original_verbosity = $VERBOSE
164
- $VERBOSE = nil
165
- text = template % tokens
166
-
167
- if full?
168
- rule_name = messages.rule(rule, opts) || rule
169
- "#{rule_name} #{text}"
170
- else
171
- text
172
- end
173
- ensure
174
- $VERBOSE = original_verbosity
175
- end
176
-
177
- def message_tokens(args)
178
- args.each_with_object({}) { |arg, hash|
179
- case arg[1]
180
- when Array
181
- hash[arg[0]] = arg[1].join(LIST_SEPARATOR)
182
- when Range
183
- hash["#{arg[0]}_left".to_sym] = arg[1].first
184
- hash["#{arg[0]}_right".to_sym] = arg[1].last
185
- else
186
- hash[arg[0]] = arg[1]
187
- end
188
- }
189
- end
190
- end
191
- end
192
- end
@@ -1,37 +0,0 @@
1
- module Dry
2
- module Validation
3
- class MessageCompiler
4
- class VisitorOpts < Hash
5
- def self.new
6
- opts = super
7
- opts[:path] = EMPTY_ARRAY
8
- opts[:rule] = nil
9
- opts[:message_type] = :failure
10
- opts
11
- end
12
-
13
- def path?
14
- ! path.empty?
15
- end
16
-
17
- def path
18
- self[:path]
19
- end
20
-
21
- def rule
22
- self[:rule]
23
- end
24
-
25
- def with_rule(new_rule, **other)
26
- opts = dup
27
- opts[:rule] = new_rule unless opts.rule
28
- opts.(other)
29
- end
30
-
31
- def call(other)
32
- merge(other.update(path: [*path, *other[:path]]))
33
- end
34
- end
35
- end
36
- end
37
- end
@@ -1,14 +0,0 @@
1
- module Dry
2
- module Validation
3
- module Messages
4
- def self.default
5
- Messages::YAML.load
6
- end
7
- end
8
- end
9
- end
10
-
11
- require 'dry/validation/messages/abstract'
12
- require 'dry/validation/messages/namespaced'
13
- require 'dry/validation/messages/yaml'
14
- require 'dry/validation/messages/i18n' if defined?(I18n)
@@ -1,112 +0,0 @@
1
- require 'pathname'
2
- require 'concurrent/map'
3
- require 'dry/equalizer'
4
- require 'dry/configurable'
5
-
6
- module Dry
7
- module Validation
8
- module Messages
9
- class Abstract
10
- extend Dry::Configurable
11
- include Dry::Equalizer(:config)
12
-
13
- DEFAULT_PATH = Pathname(__dir__).join('../../../../config/errors.yml').realpath.freeze
14
-
15
- setting :paths, [DEFAULT_PATH]
16
- setting :root, 'errors'.freeze
17
- setting :lookup_options, [:root, :predicate, :rule, :val_type, :arg_type].freeze
18
-
19
- setting :lookup_paths, %w(
20
- %{root}.rules.%{rule}.%{predicate}.arg.%{arg_type}
21
- %{root}.rules.%{rule}.%{predicate}
22
- %{root}.%{predicate}.%{message_type}
23
- %{root}.%{predicate}.value.%{rule}.arg.%{arg_type}
24
- %{root}.%{predicate}.value.%{rule}
25
- %{root}.%{predicate}.value.%{val_type}.arg.%{arg_type}
26
- %{root}.%{predicate}.value.%{val_type}
27
- %{root}.%{predicate}.arg.%{arg_type}
28
- %{root}.%{predicate}
29
- ).freeze
30
-
31
- setting :arg_type_default, 'default'.freeze
32
- setting :val_type_default, 'default'.freeze
33
-
34
- setting :arg_types, Hash.new { |*| config.arg_type_default }.update(
35
- Range => 'range'
36
- )
37
-
38
- setting :val_types, Hash.new { |*| config.val_type_default }.update(
39
- Range => 'range',
40
- String => 'string'
41
- )
42
-
43
- def self.cache
44
- @cache ||= Concurrent::Map.new { |h, k| h[k] = Concurrent::Map.new }
45
- end
46
-
47
- attr_reader :config
48
-
49
- def initialize
50
- @config = self.class.config
51
- end
52
-
53
- def hash
54
- @hash ||= config.hash
55
- end
56
-
57
- def rule(name, options = {})
58
- path = "%{locale}.rules.#{name}"
59
- get(path, options) if key?(path, options)
60
- end
61
-
62
- def call(*args)
63
- cache.fetch_or_store(args.hash) do
64
- path, opts = lookup(*args)
65
- get(path, opts) if path
66
- end
67
- end
68
- alias_method :[], :call
69
-
70
- def lookup(predicate, options = {})
71
- tokens = options.merge(
72
- root: root,
73
- predicate: predicate,
74
- arg_type: config.arg_types[options[:arg_type]],
75
- val_type: config.val_types[options[:val_type]],
76
- message_type: options[:message_type] || :failure
77
- )
78
-
79
- tokens[:rule] = predicate unless tokens.key?(:rule)
80
-
81
- opts = options.select { |k, _| !config.lookup_options.include?(k) }
82
-
83
- path = lookup_paths(tokens).detect do |key|
84
- key?(key, opts) && get(key, opts).is_a?(String)
85
- end
86
-
87
- [path, opts]
88
- end
89
-
90
- def lookup_paths(tokens)
91
- config.lookup_paths.map { |path| path % tokens }
92
- end
93
-
94
- def namespaced(namespace)
95
- Messages::Namespaced.new(namespace, self)
96
- end
97
-
98
- def root
99
- config.root
100
- end
101
-
102
- def cache
103
- @cache ||= self.class.cache[self]
104
- end
105
-
106
- def default_locale
107
- :en
108
- end
109
- end
110
- end
111
- end
112
- end