lib/dagger/vertex.rb in ruby-dagger-0.1.1 vs lib/dagger/vertex.rb in ruby-dagger-0.2.0

- old
+ new

@@ -1,59 +1,119 @@ +# frozen_string_literal: true + require 'key_tree' +require 'key_tree/refinements' require_relative 'default' module Dagger # Vertex class for Dagger, representing a filesystem directory + # + # dir/ + # file.yaml => keytree + # prefix@file.yaml => prefix.keytree + # + # +forest+ = [ +meta+ = {}, + # +local+ [ { file_keys }, ... ], + # [ { Default } ], + # +inherited+ = [ [ parent ], ... ] + # ] + # class Vertex - def initialize(name) - initialize_forest + using KeyTree::Refinements - meta['_meta.name'] = name - meta['_meta.basename'] = File.basename(name) - meta['_meta.dirname'] = File.dirname(name) + def initialize(name, cached: false) + @forest = initialize_forest(cached) + @meta['_meta.name'] = name + @meta['_meta.basename'] = File.basename(name) + @meta['_meta.dirname'] = File.dirname(name) end - attr_reader :inherited, :keys, :local, :meta + def to_key_forest + @forest + end + alias to_key_wood to_key_forest def name - meta['_meta.name'] + @forest['_meta.name'] end + alias to_s name def [](key) - key = KeyTree::Path[key] unless key.is_a? KeyTree::Path - return inherited[key[1..-1]] if key.prefix?(KeyTree::Path['^']) - keys[key] + key = key.to_key_path + @inherited[key.drop(1)] if key.prefix?('^') + @forest[key] end - def fetch(key) - keys.fetch(key) + def fetch(key, *default, &block) + key = key.to_key_path + @inherited.fetch(key.drop(1), *default, &block) if key.prefix?('^') + @forest.fetch(key, *default, &block) end def <<(keytree) - local << keytree + @local << keytree end def edge_added(edge) return unless edge.head?(self) - inherited << edge.tail.keys + @inherited << edge.tail.to_key_wood end def edge_removed(edge) return unless edge.head?(self) - inherited.reject! { |tree| tree.equal?(edge.tail.keys) } + @inherited.reject! { |tree| tree.equal?(edge.tail.to_key_wood) } end - alias to_s name + def added_to_graph(graph) + raise %(belongs another graph) if @graph&.!= graph + @graph = graph + end + def removed_from_graph(graph) + raise %(not part of graph) if @graph&.!= graph + @graph = nil + end + + def flatten(cleanup: true) + forest = initialize_forest(true) + + forest.key_paths.select { |key| key.prefix?('_default') }.each do |key| + forest[key.drop(1)] + end + + flattened = forest.flatten + return flattened unless cleanup + flattened.to_h.delete_if { |key| key.to_s.start_with?('_') } + flattened + end + + def to_h + flatten(cleanup: true).to_h + end + + def to_yaml + flatten(cleanup: true).to_yaml + end + + def to_json + flatten(cleanup: true).to_json + end + private - def initialize_forest - @keys = KeyTree::Forest.new - @keys << @meta = KeyTree::Tree.new - @keys << @local = KeyTree::Forest.new - @keys << @default = KeyTree::Forest.new - @keys << @inherited = KeyTree::Forest.new - default_proc = Default.new(self).default_proc - @default << KeyTree::Tree.new(&default_proc) + def initialize_forest(cached) + forest = KeyTree::Forest.new + forest << @meta ||= KeyTree::Tree.new + forest << @local ||= KeyTree::Forest.new + forest << default = KeyTree::Forest.new + forest << @inherited ||= KeyTree::Forest.new + default << initialize_default_tree(cached) + forest + end + + def initialize_default_tree(cached) + default_args = cached ? { cached: true, fallback: @inherited } : {} + default_proc = Default.proc(self, default_args) + KeyTree::Tree.new(&default_proc) end end end