Sha256: 20843f2d9037e4554c15c523cb5c2377c6f4e4b3b36056b00266199f738089be
Contents?: true
Size: 1.76 KB
Versions: 3
Compression:
Stored size: 1.76 KB
Contents
# frozen_string_literal: true require "dry/initializer" require "dry/schema/constants" module Dry module Schema # @api private class KeyValidator extend Dry::Initializer INDEX_REGEX = /\[\d+\]/.freeze DIGIT_REGEX = /\A\d+\z/.freeze BRACKETS = "[]" # @api private option :key_map # @api private 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 = if path[INDEX_REGEX] key = path.gsub(INDEX_REGEX, BRACKETS) if key_paths.none? { |key_path| key_path.include?(key) } arr = path.gsub(INDEX_REGEX) { |m| ".#{m[1]}" } arr.split(DOT).map { |s| DIGIT_REGEX.match?(s) ? s.to_i : s.to_sym } end elsif key_paths.none? { |key_path| key_path.include?(path) } path end next unless error_path result.add_error([:unexpected_key, [error_path, input]]) end result end private # @api private def key_paths(hash) hash.flat_map { |key, _| case (value = hash[key]) when Hash next key.to_s if value.empty? [key].product(key_paths(hash[key])).map { |keys| keys.join(DOT) } when Array hashes_or_arrays = value.select { |e| (e.is_a?(Array) || e.is_a?(Hash)) && !e.empty? } next key.to_s if hashes_or_arrays.empty? hashes_or_arrays.flat_map.with_index { |el, idx| key_paths(el).map { |path| ["#{key}[#{idx}]", *path].join(DOT) } } else key.to_s end } end end end end
Version data entries
3 entries across 3 versions & 1 rubygems
Version | Path |
---|---|
dry-schema-1.8.0 | lib/dry/schema/key_validator.rb |
dry-schema-1.7.1 | lib/dry/schema/key_validator.rb |
dry-schema-1.7.0 | lib/dry/schema/key_validator.rb |