module Eco module Data module Hashes class DiffResult attr_reader :key attr_reader :src1, :src2 # @param compare [Array, sym] # - `:all` compares the matching attrs between both hashes only def initialize(src1, src2, key:, compare: :all, case_sensitive: false) @key = key @compare = compare @case_sensitive = case_sensitive @src1 = src1 @src2 = src2 end def new? !src1 && !!src2 end def del? !!src1 && !src2 end def update? !new? && !del? && diff? end def diff? new? || del? || !diff_attrs.empty? end # Is the key attr value changing? def key? !(new? || del?) && diff_attr?(key) end def diff_attr?(attr) return true if new? return true if del? diff_attrs.include?(attr.to_s) end def attr(attr) return nil unless src2 src2[attr.to_s] end def attr_prev(attr) return nil unless src1 src1[attr.to_s] end def previous(attr) src1 && src1[attr.to_s] end def diff_hash target_attrs = [key] | compared_attrs return src2.slice(*target_attrs) if new? return src1.slice(key) if del? src2.slice(key, *diff_attrs) end def diff_attrs @diff_attrs ||= comparable_attrs.each_with_object([]) do |attr, out| out << attr unless eq?(src1[attr], src2[attr]) end end def eq?(val1, val2) return true if val1 == val2 return false if case_sensitive? return false if !val2 || !val1 val1.upcase == val2.upcase end def case_sensitive? !!@case_sensitive end def comparable_attrs return [] if new? || del? compared_attrs end def compared_attrs return @compared_attrs if instance_variable_defined?(:@compared_attrs) @compared_attrs = \ if @compare == :all src1.keys & src2.keys elsif @compare.is_a?(Array) @compare.map(&:to_s) else raise "Expecting 'compare' to be sym (:all) or Array. Given: #{@compare.class}" end end end end end end