class Quby::Compiler::Services::SeedDiff

Public Instance Methods

apply_patch(object, patch) click to toggle source
# File lib/quby/compiler/services/seed_diff.rb, line 11
def apply_patch(object, patch)
  return object if patch.nil?
  apply_polymorphic(object, patch, path: "")
end
format_patch(reference, candidate, path:) click to toggle source
# File lib/quby/compiler/services/seed_diff.rb, line 5
def format_patch(reference, candidate, path:)
  @reference_for_debugging = reference
  @candidate_for_debugging = candidate
  format_polymorph_patch(reference, candidate, path: path)
end

Private Instance Methods

apply_array(object, patch, path:) click to toggle source
# File lib/quby/compiler/services/seed_diff.rb, line 95
def apply_array(object, patch, path:)
  object ||= []

  patch.each do |key, val|
    next if key == :__patch_type__ || key == :__patch_trim__
    object[key] = val
  end

  if patch[:__patch_trim__]
    object = object.slice(0, patch[:__patch_trim__])
  end

  object
end
apply_hash(object, patch, path:) click to toggle source
# File lib/quby/compiler/services/seed_diff.rb, line 85
def apply_hash(object, patch, path:)
  object = {} unless object.is_a?(Hash)

  patch.each do |key, value|
    object[key] = apply_polymorphic(object[key], value, path: path + ".#{key}")
  end

  object
end
apply_polymorphic(object, patch, path:) click to toggle source
# File lib/quby/compiler/services/seed_diff.rb, line 72
def apply_polymorphic(object, patch, path:)
  if patch.is_a?(Hash) && patch[:__patch_type__] == "array"
    apply_array(object, patch, path: path)
  elsif patch.is_a?(Hash)
    apply_hash(object, patch, path: path)
  else
    patch
  end
rescue Exception => e
  puts "path: #{path}"
  raise
end
depends_relation?(path) click to toggle source
# File lib/quby/compiler/services/seed_diff.rb, line 110
def depends_relation?(path)
  path.end_with?(".depends")
end
format_array_patch(reference, candidate, path:) click to toggle source
# File lib/quby/compiler/services/seed_diff.rb, line 54
def format_array_patch(reference, candidate, path:)
  return reference if candidate.nil?

  patch = { __patch_type__: "array" }

  reference.each_with_index do |reference_elm, idx|
    if reference_elm != candidate[idx]
      patch[idx] = reference_elm
    end
  end

  if candidate.size > reference.size
    patch[:__patch_trim__] = reference.size
  end

  patch
end
format_hash_patch(reference, candidate, path:) click to toggle source
# File lib/quby/compiler/services/seed_diff.rb, line 40
def format_hash_patch(reference, candidate, path:)
  return reference if candidate.nil?

  patch = {}

  reference.keys.each do |key|
    if reference[key] != candidate[key]
      patch[key] = format_polymorph_patch(reference[key], candidate[key], path: path + ".#{key}")
    end
  end

  patch
end
format_polymorph_patch(reference, candidate, path:) click to toggle source
# File lib/quby/compiler/services/seed_diff.rb, line 18
def format_polymorph_patch(reference, candidate, path:)
  if reference.class != candidate.class && !candidate.nil? && !depends_relation?(path)
    raise "Incompatible types at #{path}: #{reference.class} and #{candidate.class}"
  end

  case reference
  when Hash
    case candidate
    when Hash
      format_hash_patch(reference, candidate, path: path)
    else
      reference
    end
  when Array
    format_array_patch(reference, candidate, path: path)
  when String, Symbol, true, false
    reference
  else
    raise "Cannot patch #{reference.class} yet."
  end
end