lib/dry/validation/hint_compiler.rb in dry-validation-0.8.0 vs lib/dry/validation/hint_compiler.rb in dry-validation-0.9.0
- old
+ new
@@ -1,10 +1,10 @@
-require 'dry/validation/error_compiler/input'
+require 'dry/validation/message_compiler'
module Dry
module Validation
- class HintCompiler < ErrorCompiler::Input
+ class HintCompiler < MessageCompiler
include Dry::Equalizer(:messages, :rules, :options)
attr_reader :rules, :excluded, :cache
TYPES = {
@@ -19,118 +19,86 @@
time?: Time,
hash?: Hash,
array?: Array
}.freeze
- EXCLUDED = [:none?, :filled?, :key?].freeze
+ EXCLUDED = (%i(key? none? filled?) + TYPES.keys).freeze
- DEFAULT_OPTIONS = { name: nil, input: nil, message_type: :hint }.freeze
-
- EMPTY_MESSAGES = {}.freeze
-
def self.cache
@cache ||= Concurrent::Map.new
end
def initialize(messages, options = {})
- super(messages, DEFAULT_OPTIONS.merge(options))
- @rules = @options.delete(:rules)
- @excluded = @options.fetch(:excluded, EXCLUDED)
- @val_type = options[:val_type]
+ super(messages, options)
+ @rules = options.fetch(:rules, EMPTY_ARRAY)
+ @excluded = options.fetch(:excluded, EXCLUDED)
@cache = self.class.cache
end
- def hash
- @hash ||= [messages, rules, options].hash
+ def message_type
+ :hint
end
- def with(new_options)
- return self if new_options.empty?
- super(new_options.merge(rules: rules))
+ def message_class
+ Hint
end
+ def hash
+ @hash ||= [messages, rules, options].hash
+ end
+
def call
cache.fetch_or_store(hash) { super(rules) }
end
- def visit_predicate(node)
- predicate, _ = node
-
- val_type = TYPES[predicate]
-
- return with(val_type: val_type) if val_type
- return EMPTY_MESSAGES if excluded.include?(predicate)
-
- super
+ def visit_predicate(node, opts = EMPTY_HASH)
+ predicate, args = node
+ return EMPTY_ARRAY if excluded.include?(predicate) || dyn_args?(args)
+ super(node, opts.merge(val_type: TYPES[predicate]))
end
- def visit_set(node)
- result = node.map do |el|
- visit(el)
- end
- merge(result)
+ def visit_each(node, opts = EMPTY_HASH)
+ visit(node, opts.merge(each: true))
end
- def visit_each(node)
- visit(node)
- end
-
- def visit_or(node)
+ def visit_or(node, *args)
left, right = node
- merge([visit(left), visit(right)])
+ [Array[visit(left, *args)], Array[visit(right, *args)]].flatten
end
- def visit_and(node)
- left, right = node
-
- result = visit(left)
-
- if result.is_a?(self.class)
- result.visit(right)
- else
- visit(right)
- end
- end
-
- def visit_implication(node)
+ def visit_and(node, *args)
_, right = node
- visit(right)
+ visit(right, *args)
end
- def visit_key(node)
- name, predicate = node
- with(name: Array([*self.name, name])).visit(predicate)
- end
- alias_method :visit_attr, :visit_key
+ def visit_schema(node, opts = EMPTY_HASH)
+ path = node.config.path
+ rules = node.rule_ast
+ schema_opts = opts.merge(path: [path])
- def visit_val(node)
- visit(node)
+ rules.map { |rule| visit(rule, schema_opts) }
end
- def visit_schema(node)
- merge(node.rule_ast.map(&method(:visit)))
- end
-
def visit_check(node)
- DEFAULT_RESULT
+ EMPTY_ARRAY
end
def visit_xor(node)
- DEFAULT_RESULT
+ EMPTY_ARRAY
end
def visit_not(node)
- DEFAULT_RESULT
+ EMPTY_ARRAY
end
- def visit_type(node)
- visit(node.rule.to_ast)
+ def visit_type(node, *args)
+ visit(node.rule.to_ast, *args)
end
private
- def merge(result)
- super(result.reject { |el| el.is_a?(self.class) })
+ def dyn_args?(args)
+ args.map(&:last).any? { |a| a.is_a?(UnboundMethod) }
end
end
end
end