lib/stupidedi/values/composite_element_val.rb
# frozen_string_literal: true
module Stupidedi
using Refinements
module Values
#
# @see X222.pdf B.1.1.3.3 Composite Data Structure
#
class CompositeElementVal < AbstractElementVal
# @return [Array<SimpleElementVal>]
attr_reader :children
alias component_vals children
# @return [CompositeElementUse]
attr_reader :usage
def_delegators :@usage, :definition, :descriptor
def initialize(children, usage)
@children, @usage =
children, usage
end
# @return [CompositeElementVal]
def copy(changes = {})
CompositeElementVal.new \
changes.fetch(:children, @children),
changes.fetch(:usage, @usage)
end
def position
if @children.present?
@children.head.position
else
# GH-194
"<position unknown>"
end
end
# @return false
def leaf?
false
end
# (see AbstractVal#composite?)
# @return true
def composite?
true
end
# @return [SimpleElementVal]
def element(n)
unless n > 0
raise ArgumentError,
"n must be positive"
end
@children.at(n - 1)
end
# @return [void]
def pretty_print(q)
id = definition.bind do |d|
"[#{d.id}: #{d.name}]".bind do |s|
if usage.forbidden?
ansi.forbidden(s)
elsif usage.required?
ansi.required(s)
else
ansi.optional(s)
end
end
end
q.text(ansi.composite("CompositeElementVal#{id}"))
if empty?
q.text(ansi.composite(".empty"))
else
q.group(2, "(", ")") do
q.breakable ""
@children.each do |e|
unless q.current_group.first?
q.text ", "
q.breakable
end
q.pp e
end
end
end
end
# @return [Boolean]
def ==(other)
eql?(other) or
(other.definition == definition and
other.children == @children)
end
end
end
end