class Babl::Nodes::Concat
Public Instance Methods
dependencies()
click to toggle source
# File lib/babl/nodes/concat.rb, line 9 def dependencies Babl::Utils::Hash.deep_merge(nodes.map(&:dependencies)) end
optimize()
click to toggle source
# File lib/babl/nodes/concat.rb, line 21 def optimize optimize_empty || optimize_single || optimize_concatenated_arrays || optimize_preconcat_constant || self end
pinned_dependencies()
click to toggle source
# File lib/babl/nodes/concat.rb, line 13 def pinned_dependencies Babl::Utils::Hash.deep_merge(nodes.map(&:pinned_dependencies)) end
render(frame)
click to toggle source
# File lib/babl/nodes/concat.rb, line 29 def render(frame) out = [] nodes.each { |node| values = node.render(frame) case values when ::NilClass then nil when ::Array then out.concat(values) else raise Errors::RenderingError, "Only arrays can be concatenated\n" + frame.formatted_stack end } out end
schema()
click to toggle source
# File lib/babl/nodes/concat.rb, line 17 def schema nodes.map(&:schema).reduce(Schema::FixedArray::EMPTY) { |a, b| merge_doc(a, b) } end
Private Instance Methods
constant_to_array(constant)
click to toggle source
# File lib/babl/nodes/concat.rb, line 84 def constant_to_array(constant) case constant.schema when Schema::FixedArray FixedArray.new(constant.schema.items.each_with_index.map { |item, index| Constant.new(constant.value[index], item) }) when Schema::Primitive::NULL FixedArray::EMPTY end end
merge_doc(doc1, doc2)
click to toggle source
Merging documentations from concatenated hashes is lossy, because neither JSON-Schema or our internal representation of arrays is able to model that.
# File lib/babl/nodes/concat.rb, line 97 def merge_doc(doc1, doc2) doc1 = Schema::FixedArray::EMPTY if doc1 == Schema::Primitive::NULL doc2 = Schema::FixedArray::EMPTY if doc2 == Schema::Primitive::NULL case when Schema::Anything === doc1 || Schema::Anything === doc2 Schema::DynArray.new(Schema::Anything.instance) when Schema::FixedArray === doc1 && Schema::FixedArray === doc2 Schema::FixedArray.new(doc1.items + doc2.items) when Schema::AnyOf === doc2 Schema::AnyOf.canonicalized(doc2.choice_set.map { |c| merge_doc(doc1, c) }) when Schema::AnyOf === doc1 Schema::AnyOf.canonicalized(doc1.choice_set.map { |c| merge_doc(c, doc2) }) when Schema::DynArray === doc1 && Schema::FixedArray === doc2 Schema::DynArray.new(Schema::AnyOf.canonicalized([doc1.item] + doc2.items)) when Schema::FixedArray === doc1 && Schema::DynArray === doc2 Schema::DynArray.new(Schema::AnyOf.canonicalized(doc1.items + [doc2.item])) when Schema::DynArray === doc1 && Schema::DynArray === doc2 Schema::DynArray.new(Schema::AnyOf.canonicalized([doc1.item, doc2.item])) else raise Errors::InvalidTemplate, 'Only arrays can be concatenated' end end
optimize_concatenated_arrays()
click to toggle source
# File lib/babl/nodes/concat.rb, line 63 def optimize_concatenated_arrays optimized_nodes = nodes.map(&:optimize) return if optimized_nodes == nodes Concat.new(optimized_nodes).optimize end
optimize_empty()
click to toggle source
# File lib/babl/nodes/concat.rb, line 44 def optimize_empty Constant.new(Utils::Array::EMPTY, Schema::FixedArray::EMPTY) if nodes.empty? end
optimize_preconcat_constant()
click to toggle source
# File lib/babl/nodes/concat.rb, line 70 def optimize_preconcat_constant nodes.each_cons(2).each_with_index do |(obj1, obj2), idx| obj1 = constant_to_array(obj1) if Constant === obj1 obj2 = constant_to_array(obj2) if Constant === obj2 next unless FixedArray === obj1 && FixedArray === obj2 new_nodes = nodes.dup new_nodes[idx] = FixedArray.new(obj1.nodes + obj2.nodes) new_nodes[idx + 1] = nil return Concat.new(new_nodes.compact).optimize end nil end
optimize_single()
click to toggle source
# File lib/babl/nodes/concat.rb, line 48 def optimize_single return unless nodes.size == 1 optimized = nodes.first.optimize case optimized when FixedArray then optimized when Constant case optimized.value when ::Array then optimized when ::NilClass then FixedArray::EMPTY end end end