dry-validation 0.13.3 → 1.0.0.alpha1

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 (196) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +15 -25
  3. data/LICENSE +1 -1
  4. data/README.md +9 -4
  5. data/lib/dry-validation.rb +2 -0
  6. data/lib/dry/validation.rb +8 -35
  7. data/lib/dry/validation/constants.rb +12 -0
  8. data/lib/dry/validation/contract.rb +132 -0
  9. data/lib/dry/validation/contract/class_interface.rb +114 -0
  10. data/lib/dry/validation/evaluator.rb +121 -0
  11. data/lib/dry/validation/extensions/monads.rb +23 -7
  12. data/lib/dry/validation/messages.rb +50 -6
  13. data/lib/dry/validation/result.rb +109 -45
  14. data/lib/dry/validation/rule.rb +37 -0
  15. data/lib/dry/validation/version.rb +3 -1
  16. metadata +36 -337
  17. data/.codeclimate.yml +0 -17
  18. data/.gitignore +0 -9
  19. data/.rspec +0 -3
  20. data/.travis.yml +0 -29
  21. data/CONTRIBUTING.md +0 -31
  22. data/Gemfile +0 -25
  23. data/Rakefile +0 -22
  24. data/benchmarks/benchmark_form_invalid.rb +0 -64
  25. data/benchmarks/benchmark_form_valid.rb +0 -64
  26. data/benchmarks/benchmark_schema_invalid_huge.rb +0 -52
  27. data/benchmarks/profile_schema_call_invalid.rb +0 -20
  28. data/benchmarks/profile_schema_call_valid.rb +0 -20
  29. data/benchmarks/profile_schema_definition.rb +0 -14
  30. data/benchmarks/profile_schema_huge_invalid.rb +0 -30
  31. data/benchmarks/profile_schema_messages_invalid.rb +0 -20
  32. data/benchmarks/suite.rb +0 -5
  33. data/config/errors.yml +0 -89
  34. data/dry-validation.gemspec +0 -28
  35. data/examples/basic.rb +0 -15
  36. data/examples/each.rb +0 -14
  37. data/examples/json.rb +0 -12
  38. data/examples/multiple.rb +0 -27
  39. data/examples/nested.rb +0 -22
  40. data/examples/params.rb +0 -11
  41. data/lib/dry/validation/compat/form.rb +0 -67
  42. data/lib/dry/validation/deprecations.rb +0 -24
  43. data/lib/dry/validation/executor.rb +0 -91
  44. data/lib/dry/validation/extensions.rb +0 -7
  45. data/lib/dry/validation/extensions/struct.rb +0 -32
  46. data/lib/dry/validation/input_processor_compiler.rb +0 -137
  47. data/lib/dry/validation/input_processor_compiler/json.rb +0 -45
  48. data/lib/dry/validation/input_processor_compiler/params.rb +0 -49
  49. data/lib/dry/validation/input_processor_compiler/sanitizer.rb +0 -47
  50. data/lib/dry/validation/message.rb +0 -98
  51. data/lib/dry/validation/message_compiler.rb +0 -188
  52. data/lib/dry/validation/message_compiler/visitor_opts.rb +0 -37
  53. data/lib/dry/validation/message_set.rb +0 -122
  54. data/lib/dry/validation/messages/abstract.rb +0 -119
  55. data/lib/dry/validation/messages/i18n.rb +0 -47
  56. data/lib/dry/validation/messages/namespaced.rb +0 -39
  57. data/lib/dry/validation/messages/yaml.rb +0 -61
  58. data/lib/dry/validation/predicate_registry.rb +0 -115
  59. data/lib/dry/validation/predicates.rb +0 -19
  60. data/lib/dry/validation/schema.rb +0 -126
  61. data/lib/dry/validation/schema/check.rb +0 -37
  62. data/lib/dry/validation/schema/class_interface.rb +0 -190
  63. data/lib/dry/validation/schema/deprecated.rb +0 -30
  64. data/lib/dry/validation/schema/dsl.rb +0 -118
  65. data/lib/dry/validation/schema/form.rb +0 -9
  66. data/lib/dry/validation/schema/json.rb +0 -21
  67. data/lib/dry/validation/schema/key.rb +0 -71
  68. data/lib/dry/validation/schema/params.rb +0 -22
  69. data/lib/dry/validation/schema/rule.rb +0 -202
  70. data/lib/dry/validation/schema/value.rb +0 -211
  71. data/lib/dry/validation/schema_compiler.rb +0 -81
  72. data/lib/dry/validation/template.rb +0 -66
  73. data/lib/dry/validation/type_specs.rb +0 -70
  74. data/spec/extensions/monads/result_spec.rb +0 -40
  75. data/spec/extensions/struct/schema_spec.rb +0 -32
  76. data/spec/fixtures/locales/en.yml +0 -8
  77. data/spec/fixtures/locales/pl.yml +0 -22
  78. data/spec/integration/custom_error_messages_spec.rb +0 -54
  79. data/spec/integration/custom_predicates_spec.rb +0 -228
  80. data/spec/integration/hints_spec.rb +0 -170
  81. data/spec/integration/injecting_rules_spec.rb +0 -30
  82. data/spec/integration/json/defining_base_schema_spec.rb +0 -41
  83. data/spec/integration/localized_error_messages_spec.rb +0 -72
  84. data/spec/integration/message_compiler_spec.rb +0 -405
  85. data/spec/integration/messages/i18n_spec.rb +0 -104
  86. data/spec/integration/optional_keys_spec.rb +0 -28
  87. data/spec/integration/params/predicates/array_spec.rb +0 -287
  88. data/spec/integration/params/predicates/empty_spec.rb +0 -263
  89. data/spec/integration/params/predicates/eql_spec.rb +0 -327
  90. data/spec/integration/params/predicates/even_spec.rb +0 -455
  91. data/spec/integration/params/predicates/excluded_from_spec.rb +0 -455
  92. data/spec/integration/params/predicates/excludes_spec.rb +0 -391
  93. data/spec/integration/params/predicates/false_spec.rb +0 -455
  94. data/spec/integration/params/predicates/filled_spec.rb +0 -467
  95. data/spec/integration/params/predicates/format_spec.rb +0 -454
  96. data/spec/integration/params/predicates/gt_spec.rb +0 -519
  97. data/spec/integration/params/predicates/gteq_spec.rb +0 -519
  98. data/spec/integration/params/predicates/included_in_spec.rb +0 -455
  99. data/spec/integration/params/predicates/includes_spec.rb +0 -391
  100. data/spec/integration/params/predicates/key_spec.rb +0 -67
  101. data/spec/integration/params/predicates/lt_spec.rb +0 -519
  102. data/spec/integration/params/predicates/lteq_spec.rb +0 -519
  103. data/spec/integration/params/predicates/max_size_spec.rb +0 -391
  104. data/spec/integration/params/predicates/min_size_spec.rb +0 -391
  105. data/spec/integration/params/predicates/none_spec.rb +0 -265
  106. data/spec/integration/params/predicates/not_eql_spec.rb +0 -327
  107. data/spec/integration/params/predicates/odd_spec.rb +0 -455
  108. data/spec/integration/params/predicates/size/fixed_spec.rb +0 -393
  109. data/spec/integration/params/predicates/size/range_spec.rb +0 -396
  110. data/spec/integration/params/predicates/true_spec.rb +0 -455
  111. data/spec/integration/params/predicates/type_spec.rb +0 -391
  112. data/spec/integration/result_spec.rb +0 -81
  113. data/spec/integration/schema/array_schema_spec.rb +0 -59
  114. data/spec/integration/schema/check_rules_spec.rb +0 -119
  115. data/spec/integration/schema/check_with_nested_el_spec.rb +0 -37
  116. data/spec/integration/schema/check_with_nth_el_spec.rb +0 -25
  117. data/spec/integration/schema/default_settings_spec.rb +0 -11
  118. data/spec/integration/schema/defining_base_schema_spec.rb +0 -41
  119. data/spec/integration/schema/dynamic_predicate_args_spec.rb +0 -43
  120. data/spec/integration/schema/each_with_set_spec.rb +0 -70
  121. data/spec/integration/schema/extending_dsl_spec.rb +0 -27
  122. data/spec/integration/schema/form_spec.rb +0 -236
  123. data/spec/integration/schema/hash_schema_spec.rb +0 -47
  124. data/spec/integration/schema/inheriting_schema_spec.rb +0 -31
  125. data/spec/integration/schema/input_processor_spec.rb +0 -46
  126. data/spec/integration/schema/json/explicit_types_spec.rb +0 -157
  127. data/spec/integration/schema/json_spec.rb +0 -163
  128. data/spec/integration/schema/macros/confirmation_spec.rb +0 -35
  129. data/spec/integration/schema/macros/each_spec.rb +0 -268
  130. data/spec/integration/schema/macros/filled_spec.rb +0 -87
  131. data/spec/integration/schema/macros/input_spec.rb +0 -139
  132. data/spec/integration/schema/macros/maybe_spec.rb +0 -99
  133. data/spec/integration/schema/macros/rule_spec.rb +0 -75
  134. data/spec/integration/schema/macros/value_spec.rb +0 -119
  135. data/spec/integration/schema/macros/when_spec.rb +0 -62
  136. data/spec/integration/schema/nested_schemas_spec.rb +0 -236
  137. data/spec/integration/schema/nested_values_spec.rb +0 -46
  138. data/spec/integration/schema/not_spec.rb +0 -34
  139. data/spec/integration/schema/numbers_spec.rb +0 -19
  140. data/spec/integration/schema/option_with_default_spec.rb +0 -64
  141. data/spec/integration/schema/or_spec.rb +0 -87
  142. data/spec/integration/schema/params/defining_base_schema_spec.rb +0 -41
  143. data/spec/integration/schema/params/explicit_types_spec.rb +0 -195
  144. data/spec/integration/schema/params_spec.rb +0 -234
  145. data/spec/integration/schema/predicate_verification_spec.rb +0 -9
  146. data/spec/integration/schema/predicates/array_spec.rb +0 -295
  147. data/spec/integration/schema/predicates/custom_spec.rb +0 -103
  148. data/spec/integration/schema/predicates/empty_spec.rb +0 -263
  149. data/spec/integration/schema/predicates/eql_spec.rb +0 -327
  150. data/spec/integration/schema/predicates/even_spec.rb +0 -455
  151. data/spec/integration/schema/predicates/excluded_from/array_spec.rb +0 -459
  152. data/spec/integration/schema/predicates/excluded_from/range_spec.rb +0 -459
  153. data/spec/integration/schema/predicates/excludes_spec.rb +0 -391
  154. data/spec/integration/schema/predicates/filled_spec.rb +0 -467
  155. data/spec/integration/schema/predicates/format_spec.rb +0 -455
  156. data/spec/integration/schema/predicates/gt_spec.rb +0 -519
  157. data/spec/integration/schema/predicates/gteq_spec.rb +0 -519
  158. data/spec/integration/schema/predicates/hash_spec.rb +0 -69
  159. data/spec/integration/schema/predicates/included_in/array_spec.rb +0 -459
  160. data/spec/integration/schema/predicates/included_in/range_spec.rb +0 -459
  161. data/spec/integration/schema/predicates/includes_spec.rb +0 -391
  162. data/spec/integration/schema/predicates/key_spec.rb +0 -88
  163. data/spec/integration/schema/predicates/lt_spec.rb +0 -520
  164. data/spec/integration/schema/predicates/lteq_spec.rb +0 -519
  165. data/spec/integration/schema/predicates/max_size_spec.rb +0 -391
  166. data/spec/integration/schema/predicates/min_size_spec.rb +0 -391
  167. data/spec/integration/schema/predicates/none_spec.rb +0 -265
  168. data/spec/integration/schema/predicates/not_eql_spec.rb +0 -391
  169. data/spec/integration/schema/predicates/odd_spec.rb +0 -455
  170. data/spec/integration/schema/predicates/size/fixed_spec.rb +0 -398
  171. data/spec/integration/schema/predicates/size/range_spec.rb +0 -395
  172. data/spec/integration/schema/predicates/type_spec.rb +0 -413
  173. data/spec/integration/schema/reusing_schema_spec.rb +0 -33
  174. data/spec/integration/schema/using_types_spec.rb +0 -135
  175. data/spec/integration/schema/validate_spec.rb +0 -120
  176. data/spec/integration/schema/xor_spec.rb +0 -35
  177. data/spec/integration/schema_builders_spec.rb +0 -17
  178. data/spec/integration/schema_spec.rb +0 -173
  179. data/spec/shared/message_compiler.rb +0 -11
  180. data/spec/shared/predicate_helper.rb +0 -15
  181. data/spec/shared/rule_compiler.rb +0 -8
  182. data/spec/spec_helper.rb +0 -62
  183. data/spec/support/define_struct.rb +0 -25
  184. data/spec/support/matchers.rb +0 -38
  185. data/spec/support/mutant.rb +0 -9
  186. data/spec/support/predicates_integration.rb +0 -7
  187. data/spec/unit/input_processor_compiler/json_spec.rb +0 -283
  188. data/spec/unit/input_processor_compiler/params_spec.rb +0 -328
  189. data/spec/unit/message_compiler/visit_failure_spec.rb +0 -38
  190. data/spec/unit/message_compiler/visit_spec.rb +0 -16
  191. data/spec/unit/message_compiler_spec.rb +0 -7
  192. data/spec/unit/predicate_registry_spec.rb +0 -34
  193. data/spec/unit/schema/key_spec.rb +0 -38
  194. data/spec/unit/schema/rule_spec.rb +0 -42
  195. data/spec/unit/schema/value_spec.rb +0 -131
  196. data/spec/unit/schema_spec.rb +0 -35
@@ -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,122 +0,0 @@
1
- module Dry
2
- module Validation
3
- class MessageSet
4
- include Enumerable
5
-
6
- HINT_EXCLUSION = %i(
7
- key? filled? none? bool?
8
- str? int? float? decimal?
9
- date? date_time? time? hash?
10
- array? format?
11
- ).freeze
12
-
13
- attr_reader :messages, :failures, :hints, :paths, :placeholders, :options
14
-
15
- def self.[](messages, options = EMPTY_HASH)
16
- new(messages.flatten, options)
17
- end
18
-
19
- def initialize(messages, options = EMPTY_HASH)
20
- @messages = messages
21
- @hints = messages.select(&:hint?)
22
- @failures = messages - hints
23
- @paths = failures.map(&:path).uniq
24
- @options = options
25
-
26
- initialize_hints!
27
- initialize_placeholders!
28
- end
29
-
30
- def dump
31
- root? ? to_a : to_h
32
- end
33
-
34
- def failures?
35
- options[:failures].equal?(true)
36
- end
37
-
38
- def empty?
39
- messages.empty?
40
- end
41
-
42
- def root?
43
- !empty? && failures.all?(&:root?)
44
- end
45
-
46
- def each(&block)
47
- return to_enum unless block
48
- messages.each(&block)
49
- end
50
-
51
- def to_h
52
- if root?
53
- { nil => failures.map(&:to_s) }
54
- else
55
- failures? ? messages_map : hints_map
56
- end
57
- end
58
- alias_method :to_hash, :to_h
59
-
60
- def to_a
61
- to_h.values.flatten
62
- end
63
-
64
- private
65
-
66
- def messages_map
67
- failures.group_by(&:path).reduce(placeholders) do |hash, (path, msgs)|
68
- node = path.reduce(hash) { |a, e| a[e] }
69
-
70
- msgs.each do |msg|
71
- node << msg
72
-
73
- msg_hints = hint_groups[msg.path]
74
- node.concat(msg_hints) if msg_hints
75
- end
76
-
77
- node.map!(&:to_s)
78
-
79
- hash
80
- end
81
- end
82
-
83
- def hints_map
84
- hints.group_by(&:path).reduce(placeholders) do |hash, (path, msgs)|
85
- node = path.reduce(hash) { |a, e| a[e] }
86
-
87
- msgs.each do |msg|
88
- node << msg
89
- end
90
-
91
- node.map!(&:to_s)
92
-
93
- hash
94
- end
95
- end
96
-
97
- def hint_groups
98
- @hint_groups ||= hints.group_by(&:path)
99
- end
100
-
101
- def initialize_hints!
102
- hints.reject! { |hint| HINT_EXCLUSION.include?(hint.predicate) }
103
- end
104
-
105
- def initialize_placeholders!
106
- @placeholders = paths.reduce({}) do |hash, path|
107
- curr_idx = 0
108
- last_idx = path.size - 1
109
- node = hash
110
-
111
- while curr_idx <= last_idx do
112
- key = path[curr_idx]
113
- node = (node[key] || node[key] = curr_idx < last_idx ? {} : [])
114
- curr_idx += 1
115
- end
116
-
117
- hash
118
- end
119
- end
120
- end
121
- end
122
- end
@@ -1,119 +0,0 @@
1
- require 'pathname'
2
- require 'concurrent/map'
3
-
4
- require 'dry/equalizer'
5
- require 'dry/configurable'
6
-
7
- require 'dry/validation/template'
8
-
9
- module Dry
10
- module Validation
11
- module Messages
12
- class Abstract
13
- extend Dry::Configurable
14
- include Dry::Equalizer(:config)
15
-
16
- DEFAULT_PATH = Pathname(__dir__).join('../../../../config/errors.yml').realpath.freeze
17
-
18
- setting :paths, [DEFAULT_PATH]
19
- setting :root, 'errors'.freeze
20
- setting :lookup_options, [:root, :predicate, :rule, :val_type, :arg_type].freeze
21
-
22
- setting :lookup_paths, %w(
23
- %{root}.rules.%{rule}.%{predicate}.arg.%{arg_type}
24
- %{root}.rules.%{rule}.%{predicate}
25
- %{root}.%{predicate}.%{message_type}
26
- %{root}.%{predicate}.value.%{rule}.arg.%{arg_type}
27
- %{root}.%{predicate}.value.%{rule}
28
- %{root}.%{predicate}.value.%{val_type}.arg.%{arg_type}
29
- %{root}.%{predicate}.value.%{val_type}
30
- %{root}.%{predicate}.arg.%{arg_type}
31
- %{root}.%{predicate}
32
- ).freeze
33
-
34
- setting :arg_type_default, 'default'.freeze
35
- setting :val_type_default, 'default'.freeze
36
-
37
- setting :arg_types, Hash.new { |*| config.arg_type_default }.update(
38
- Range => 'range'
39
- )
40
-
41
- setting :val_types, Hash.new { |*| config.val_type_default }.update(
42
- Range => 'range',
43
- String => 'string'
44
- )
45
-
46
- CACHE_KEYS = %i[path message_type val_type arg_type locale].freeze
47
-
48
- def self.cache
49
- @cache ||= Concurrent::Map.new { |h, k| h[k] = Concurrent::Map.new }
50
- end
51
-
52
- attr_reader :config
53
-
54
- def initialize
55
- @config = self.class.config
56
- end
57
-
58
- def hash
59
- @hash ||= config.hash
60
- end
61
-
62
- def rule(name, options = {})
63
- path = "%{locale}.rules.#{name}"
64
- get(path, options) if key?(path, options)
65
- end
66
-
67
- def call(predicate, options = EMPTY_HASH)
68
- cache.fetch_or_store([predicate, options.reject { |k,| k.equal?(:input) }]) do
69
- path, opts = lookup(predicate, options)
70
- return unless path
71
- text = yield(path, opts)
72
- Template[text]
73
- end
74
- end
75
- alias_method :[], :call
76
-
77
- def lookup(predicate, options = {})
78
- tokens = options.merge(
79
- root: root,
80
- predicate: predicate,
81
- arg_type: config.arg_types[options[:arg_type]],
82
- val_type: config.val_types[options[:val_type]],
83
- message_type: options[:message_type] || :failure
84
- )
85
-
86
- tokens[:rule] = predicate unless tokens.key?(:rule)
87
-
88
- opts = options.select { |k, _| !config.lookup_options.include?(k) }
89
-
90
- path = lookup_paths(tokens).detect do |key|
91
- key?(key, opts) && get(key, opts).is_a?(String)
92
- end
93
-
94
- [path, opts]
95
- end
96
-
97
- def lookup_paths(tokens)
98
- config.lookup_paths.map { |path| path % tokens }
99
- end
100
-
101
- def namespaced(namespace)
102
- Messages::Namespaced.new(namespace, self)
103
- end
104
-
105
- def root
106
- config.root
107
- end
108
-
109
- def cache
110
- @cache ||= self.class.cache[self]
111
- end
112
-
113
- def default_locale
114
- :en
115
- end
116
- end
117
- end
118
- end
119
- end
@@ -1,47 +0,0 @@
1
- require 'i18n'
2
- require 'dry/validation/messages/abstract'
3
-
4
- module Dry
5
- module Validation
6
- class Messages::I18n < Messages::Abstract
7
- attr_reader :t
8
-
9
- ::I18n.load_path.concat(config.paths)
10
-
11
- def initialize
12
- super
13
- @t = I18n.method(:t)
14
- end
15
-
16
- def call(predicate, options = EMPTY_HASH)
17
- super do |path, opts|
18
- get(path, opts)
19
- end
20
- end
21
- alias_method :[], :call
22
-
23
- def get(key, options = {})
24
- t.(key, locale: options.fetch(:locale, default_locale)) if key
25
- end
26
-
27
- def rule(name, options = {})
28
- path = "rules.#{name}"
29
- get(path, options) if key?(path, options)
30
- end
31
-
32
- def key?(key, options)
33
- ::I18n.exists?(key, options.fetch(:locale, default_locale)) ||
34
- ::I18n.exists?(key, I18n.default_locale)
35
- end
36
-
37
- def merge(path)
38
- ::I18n.load_path << path
39
- self
40
- end
41
-
42
- def default_locale
43
- I18n.locale || I18n.default_locale || super
44
- end
45
- end
46
- end
47
- end
@@ -1,39 +0,0 @@
1
- module Dry
2
- module Validation
3
- module Messages
4
- class Namespaced < Messages::Abstract
5
- attr_reader :namespace, :messages, :root
6
-
7
- def initialize(namespace, messages)
8
- super()
9
- @namespace = namespace
10
- @messages = messages
11
- @root = messages.root
12
- end
13
-
14
- def call(predicate, options = EMPTY_HASH)
15
- super do |path, opts|
16
- messages.get(path, opts)
17
- end
18
- end
19
- alias_method :[], :call
20
-
21
- def key?(key, *args)
22
- messages.key?(key, *args)
23
- end
24
-
25
- def get(key, options = {})
26
- messages.get(key, options)
27
- end
28
-
29
- def lookup_paths(tokens)
30
- super(tokens.merge(root: "#{root}.rules.#{namespace}")) + super
31
- end
32
-
33
- def default_locale
34
- messages.default_locale
35
- end
36
- end
37
- end
38
- end
39
- end
@@ -1,61 +0,0 @@
1
- require 'yaml'
2
- require 'pathname'
3
-
4
- require 'dry/equalizer'
5
- require 'dry/validation/messages/abstract'
6
-
7
- module Dry
8
- module Validation
9
- class Messages::YAML < Messages::Abstract
10
- include Dry::Equalizer(:data)
11
-
12
- attr_reader :data
13
-
14
- configure do |config|
15
- config.root = '%{locale}.errors'.freeze
16
- end
17
-
18
- def self.load(paths = config.paths)
19
- new(paths.map { |path| load_file(path) }.reduce(:merge))
20
- end
21
-
22
- def self.load_file(path)
23
- flat_hash(YAML.load_file(path))
24
- end
25
-
26
- def self.flat_hash(h, f = [], g = {})
27
- return g.update(f.join('.'.freeze) => h) unless h.is_a? Hash
28
- h.each { |k, r| flat_hash(r, f + [k], g) }
29
- g
30
- end
31
-
32
- def initialize(data)
33
- super()
34
- @data = data
35
- end
36
-
37
- def call(predicate, options = EMPTY_HASH)
38
- super do |path, opts|
39
- get(path, opts)
40
- end
41
- end
42
- alias_method :[], :call
43
-
44
- def get(key, options = {})
45
- data[key % { locale: options.fetch(:locale, default_locale) }]
46
- end
47
-
48
- def key?(key, options = {})
49
- data.key?(key % { locale: options.fetch(:locale, default_locale) })
50
- end
51
-
52
- def merge(overrides)
53
- if overrides.is_a?(Hash)
54
- self.class.new(data.merge(self.class.flat_hash(overrides)))
55
- else
56
- self.class.new(data.merge(Messages::YAML.load_file(overrides)))
57
- end
58
- end
59
- end
60
- end
61
- end
@@ -1,115 +0,0 @@
1
- require 'dry/logic/rule/predicate'
2
-
3
- module Dry
4
- module Validation
5
- class PredicateRegistry
6
- module PredicateDetector
7
- def method_added(name)
8
- super
9
-
10
- if name.to_s.end_with?('?')
11
- registry.update(name => instance_method(name))
12
- end
13
- end
14
- end
15
-
16
- attr_reader :predicates
17
- attr_reader :external
18
-
19
- class Bound < PredicateRegistry
20
- attr_reader :schema
21
-
22
- def initialize(*args)
23
- super(*args[0..1])
24
- @schema = args.last
25
- freeze
26
- end
27
- end
28
-
29
- class Unbound < PredicateRegistry
30
- def bind(schema)
31
- bound_predicates = predicates.each_with_object({}) do |(n, p), res|
32
- res[n] = p.bind(schema)
33
- end
34
- Bound.new(external, bound_predicates, schema)
35
- end
36
-
37
- def update(other)
38
- predicates.update(other)
39
- self
40
- end
41
- end
42
-
43
- def self.[](predicates)
44
- Unbound.new(predicates)
45
- end
46
-
47
- def initialize(external, predicates = {})
48
- @external = external
49
- @predicates = predicates
50
- end
51
-
52
- def new(klass)
53
- new_predicates = predicates
54
- .keys
55
- .each_with_object({}) { |key, res| res[key] = klass.instance_method(key) }
56
-
57
- self.class.new(external).update(new_predicates)
58
- end
59
-
60
- def [](name)
61
- predicates.fetch(name) do
62
- if external.public_methods.include?(name)
63
- external[name]
64
- else
65
- raise_unknown_predicate_error(name)
66
- end
67
- end
68
- end
69
-
70
- def key?(name)
71
- predicates.key?(name) || external.public_methods.include?(name)
72
- end
73
-
74
- def arg_list(name, *values)
75
- predicate = self[name]
76
-
77
- predicate
78
- .parameters
79
- .map(&:last)
80
- .zip(values + Array.new(predicate.arity - values.size, Undefined))
81
- end
82
-
83
- def ensure_valid_predicate(name, args_or_arity, schema = nil)
84
- return if schema && schema.instance_methods.include?(name)
85
-
86
- if name == :key?
87
- raise InvalidSchemaError, "#{name} is a reserved predicate name"
88
- end
89
-
90
- if key?(name)
91
- arity = self[name].arity
92
-
93
- case args_or_arity
94
- when Array
95
- raise_invalid_arity_error(name) if ![0, args_or_arity.size + 1].include?(arity)
96
- when Integer
97
- raise_invalid_arity_error(name) if args_or_arity != arity
98
- end
99
- else
100
- raise_unknown_predicate_error(name)
101
- end
102
- end
103
-
104
- private
105
-
106
- def raise_unknown_predicate_error(name)
107
- raise ArgumentError, "+#{name}+ is not a valid predicate name"
108
- end
109
-
110
- def raise_invalid_arity_error(name)
111
- raise ArgumentError, "#{name} predicate arity is invalid"
112
- end
113
- end
114
- end
115
- end