class Metaractor::Errors
Public Class Methods
new()
click to toggle source
# File lib/metaractor/errors.rb, line 66 def initialize @tree = Sycamore::Tree.new end
Public Instance Methods
add(error: {}, errors: {}, object: nil)
click to toggle source
# File lib/metaractor/errors.rb, line 72 def add(error: {}, errors: {}, object: nil) trees = [] [error, errors].each do |h| tree = nil tree = if h.is_a? Metaractor::Errors Sycamore::Tree.from(h.instance_variable_get(:@tree)) else Sycamore::Tree.from(normalize_error_hash(h)) end unless tree.empty? if tree.nodes.any? { |node| tree.strict_leaf?(node) } raise ArgumentError, "Invalid hash!" end trees << tree end end trees.each do |tree| tree.each_path do |path| node = path.node unless node.is_a?(Error) node = Error.new( value: path.node, object: object ) end @tree[path.parent] << node end end @tree.compact end
dig(*path)
click to toggle source
# File lib/metaractor/errors.rb, line 127 def dig(*path) result = @tree.dig(*path) if result.strict_leaves? unwrapped_enum(result.nodes) else unwrapped_tree(result).to_h end end
Also aliased as: []
full_messages(tree = @tree)
click to toggle source
# File lib/metaractor/errors.rb, line 107 def full_messages(tree = @tree) messages = [] tree.each_path do |path| messages << message_from_path(path) end messages end
Also aliased as: to_a
full_messages_for(*path)
click to toggle source
# File lib/metaractor/errors.rb, line 117 def full_messages_for(*path) child_tree = @tree.fetch_path(path) if child_tree.strict_leaves? child_tree = @tree.fetch_path(path[0..-2]) end full_messages(child_tree) end
include?(*elements)
click to toggle source
# File lib/metaractor/errors.rb, line 138 def include?(*elements) if elements.size == 1 && elements.first.is_a?(Hash) unwrapped_tree.include?(*elements) elsif elements.all? { |e| e.is_a? String } full_messages.include?(*elements) else elements.all? do |element| @tree.include_path?(element) end end end
inspect()
click to toggle source
# File lib/metaractor/errors.rb, line 172 def inspect str = "<##{self.class.name}: " if !empty? str << "Errors:\n" str << Metaractor.format_hash(to_h(unwrap: false)) str << "\n" end str << ">" str end
slice(*paths)
click to toggle source
# File lib/metaractor/errors.rb, line 151 def slice(*paths) new_tree = Sycamore::Tree.new paths.each do |path| if @tree.include_path?(path) new_tree[path] = @tree[path].dup end end unwrapped_tree(new_tree).to_h end
to_h(unwrap: true)
click to toggle source
# File lib/metaractor/errors.rb, line 163 def to_h(unwrap: true) if unwrap unwrapped_tree.to_h else @tree.to_h end end
Also aliased as: to_hash
Private Instance Methods
deep_transform_values_in_object(object) { |object| ... }
click to toggle source
Lifted from Rails
# File lib/metaractor/errors.rb, line 241 def deep_transform_values_in_object(object, &block) case object when Hash object.transform_values { |value| deep_transform_values_in_object(value, &block) } when Array object.map { |e| deep_transform_values_in_object(e, &block) } else yield(object) end end
message_from_path(path)
click to toggle source
# File lib/metaractor/errors.rb, line 187 def message_from_path(path) path_elements = [] path.parent&.each_node do |node| unless node == :base path_elements << node.to_s end end path.node.generate_message(path_elements: path_elements) end
normalize_error_hash(hash)
click to toggle source
# File lib/metaractor/errors.rb, line 222 def normalize_error_hash(hash) deep_transform_values_in_object(hash, &method(:transform_delegator)) end
transform_delegator(value)
click to toggle source
# File lib/metaractor/errors.rb, line 226 def transform_delegator(value) if value.is_a?(Delegator) if value.respond_to?(:to_hash) deep_transform_values_in_object(value.to_hash, &method(:transform_delegator)) elsif value.respond_to?(:to_a) deep_transform_values_in_object(value.to_a, &method(:transform_delegator)) else value end else value end end
unwrapped_enum(orig)
click to toggle source
# File lib/metaractor/errors.rb, line 212 def unwrapped_enum(orig) orig.map do |element| if element.is_a? Error element.value else element end end end
unwrapped_tree(orig_tree = @tree)
click to toggle source
# File lib/metaractor/errors.rb, line 198 def unwrapped_tree(orig_tree = @tree) tree = Sycamore::Tree.new orig_tree.each_path do |path| node = path.node if node.is_a? Error node = node.value end tree[path.parent] << node end tree end