class Dry::Schema::Path

@api private
Path represents a list of keys in a hash

def self.[](spec)

Other tags:
    Api: - private

Returns:
  • (Path) -

Parameters:
  • spec (Path, Symbol, String, Hash, Array) --
def self.[](spec)
  case spec
  when Symbol, Array
    new(Array[*spec])
  when String
    new(spec.split(DOT).map(&:to_sym))
  when Hash
    new(keys_from_hash(spec))
  when Path
    spec
  else
    raise ArgumentError, '+spec+ must be either a Symbol, Array, Hash or a Path'
  end
end

def self.keys_from_hash(hash)

Other tags:
    Api: - private
def self.keys_from_hash(hash)
  hash.inject([]) { |a, (k, v)|
    v.is_a?(Hash) ? a.concat([k, *keys_from_hash(v)]) : a.concat([k, v])
  }
end

def <=>(other)

Other tags:
    Api: - private
def <=>(other)
  raise ArgumentError, "Can't compare paths from different branches" unless same_root?(other)
  return 0 if keys.eql?(other.keys)
  res = key_matches(other).compact.reject { |value| value.equal?(false) }
  res.size < count ? 1 : -1
end

def each(&block)

Other tags:
    Api: - private
def each(&block)
  keys.each(&block)
end

def include?(other)

Other tags:
    Api: - private
def include?(other)
  return false unless same_root?(other)
  return last.equal?(other.last) if index? && other.index?
  return self.class.new([*to_a[0..-2]]).include?(other) if index?
  self >= other && !other.key_matches(self).include?(nil)
end

def index(key)

Other tags:
    Api: - private
def index(key)
  keys.index(key)
end

def index?

Other tags:
    Api: - private
def index?
  last.is_a?(Integer)
end

def initialize(keys)

Other tags:
    Api: - private
def initialize(keys)
  @keys = keys
end

def key_matches(other)

Other tags:
    Api: - private
def key_matches(other)
  map { |key| (idx = other.index(key)) && keys[idx].equal?(key) }
end

def last

Other tags:
    Api: - private
def last
  keys.last
end

def same_root?(other)

Other tags:
    Api: - private
def same_root?(other)
  root.equal?(other.root)
end