lib/dry/schema/path.rb in dry-schema-1.6.2 vs lib/dry/schema/path.rb in dry-schema-1.7.0
- old
+ new
@@ -30,14 +30,14 @@
new(Array[*spec])
when String
new(spec.split(DOT).map(&:to_sym))
when Hash
new(keys_from_hash(spec))
- when Path
+ when self
spec
else
- raise ArgumentError, "+spec+ must be either a Symbol, Array, Hash or a Path"
+ raise ArgumentError, "+spec+ must be either a Symbol, Array, Hash or a #{name}"
end
end
# @api private
def self.[](spec)
@@ -58,100 +58,50 @@
@keys = keys
end
# @api private
def to_h(value = EMPTY_ARRAY.dup)
- curr_idx = 0
- last_idx = keys.size - 1
- hash = EMPTY_HASH.dup
- node = hash
+ value = [value] unless value.is_a?(Array)
- while curr_idx <= last_idx
- node =
- node[keys[curr_idx]] =
- if curr_idx == last_idx
- value.is_a?(Array) ? value : [value]
- else
- EMPTY_HASH.dup
- end
-
- curr_idx += 1
- end
-
- hash
+ keys.reverse_each.reduce(value) { |result, key| {key => result} }
end
# @api private
def each(&block)
keys.each(&block)
end
# @api private
- def index(key)
- keys.index(key)
- end
-
- def without_index
- self.class.new(to_a[0..-2])
- end
-
- # @api private
def include?(other)
- if !same_root?(other)
- false
- elsif index?
- if other.index?
- last.equal?(other.last)
- else
- without_index.include?(other)
- end
- elsif other.index? && key_matches(other, :select).size < 2
- false
- else
- self >= other && !other.key_matches(self).include?(nil)
- end
+ keys[0, other.keys.length].eql?(other.keys)
end
# @api private
def <=>(other)
- raise ArgumentError, "Can't compare paths from different branches" unless same_root?(other)
+ return keys.length <=> other.keys.length if include?(other) || other.include?(self)
- return 0 if keys.eql?(other.keys)
+ first_uncommon_index = (self & other).keys.length
- res = key_matches(other).compact.reject { |value| value.equal?(false) }
-
- res.size < count ? 1 : -1
+ keys[first_uncommon_index] <=> other.keys[first_uncommon_index]
end
# @api private
def &(other)
- unless same_root?(other)
- raise ArgumentError, "#{other.inspect} doesn't have the same root #{inspect}"
- end
-
self.class.new(
- key_matches(other, :select).compact.reject { |value| value.equal?(false) }
+ keys.take_while.with_index { |key, index| other.keys[index].eql?(key) }
)
end
# @api private
- def key_matches(other, meth = :map)
- public_send(meth) { |key| (idx = other.index(key)) && keys[idx].equal?(key) }
- end
-
- # @api private
def last
keys.last
end
# @api private
def same_root?(other)
root.equal?(other.root)
end
- # @api private
- def index?
- last.is_a?(Integer)
- end
+ EMPTY = new(EMPTY_ARRAY).freeze
end
end
end