class Dry::Schema::KeyValidator
@api private
Constants
- BRACKETS
- DIGIT_REGEX
- INDEX_REGEX
Public Instance Methods
call(result)
click to toggle source
@api private
# File lib/dry/schema/key_validator.rb, line 20 def call(result) input = result.to_h input_paths = key_paths(input) key_paths = key_map.to_dot_notation input_paths.each do |path| error_path = validate_path(key_paths, path) next unless error_path result.add_error([:unexpected_key, [error_path, input]]) end result end
Private Instance Methods
hashes_or_arrays(xs)
click to toggle source
@api private
# File lib/dry/schema/key_validator.rb, line 86 def hashes_or_arrays(xs) xs.select { |x| (x.is_a?(::Array) || x.is_a?(::Hash)) && !x.empty? } end
key_paths(hash)
click to toggle source
@api private
# File lib/dry/schema/key_validator.rb, line 60 def key_paths(hash) hash.flat_map { |key, value| case value when ::Hash if value.empty? [key.to_s] else [key].product(key_paths(hash[key])).map { _1.join(DOT) } end when ::Array hashes_or_arrays = hashes_or_arrays(value) if hashes_or_arrays.empty? [key.to_s] else hashes_or_arrays.flat_map.with_index { |el, idx| key_paths(el).map { ["#{key}[#{idx}]", *_1].join(DOT) } } end else key.to_s end } end
paths_match?(input_path, key_path)
click to toggle source
@api private
# File lib/dry/schema/key_validator.rb, line 54 def paths_match?(input_path, key_path) residue = key_path.sub(input_path, "") residue.empty? || residue.start_with?(DOT, BRACKETS) end
validate_path(key_paths, path)
click to toggle source
@api private
# File lib/dry/schema/key_validator.rb, line 40 def validate_path(key_paths, path) if path[INDEX_REGEX] key = path.gsub(INDEX_REGEX, BRACKETS) if key_paths.none? { paths_match?(key, _1) } arr = path.gsub(INDEX_REGEX) { ".#{_1[1]}" } arr.split(DOT).map { DIGIT_REGEX.match?(_1) ? Integer(_1, 10) : _1.to_sym } end elsif key_paths.none? { paths_match?(path, _1) } path end end