module Structured::Struct::ClassMethods

Public Instance Methods

attributes() click to toggle source
# File lib/structured/struct.rb, line 53
def attributes
  @attributes ||= {}
end
format_stack_frame_element(name) click to toggle source
# File lib/structured/struct.rb, line 90
def format_stack_frame_element(name)
  ".#{name}"
end
ignore_attribute(name) click to toggle source
# File lib/structured/struct.rb, line 68
def ignore_attribute(name)
  attributes[name.to_s] = :ignore
end
new_with_defaults() click to toggle source
# File lib/structured/struct.rb, line 81
def new_with_defaults
  new_instance = new
  attributes.each do |name, attribute|
    next if attribute == :ignore
    new_instance.send(:"#{name}=", attribute.default_value) if attribute.has_default?
  end
  new_instance
end
optional_attribute(name, type, default: Attribute::UNDEFINED) click to toggle source
# File lib/structured/struct.rb, line 62
def optional_attribute(name, type, default: Attribute::UNDEFINED)
  define_accessor(name.to_s)
  default = default == Attribute::UNDEFINED ? type.default_value : default
  attributes[name.to_s] = Attribute.new(self, type, default_value: default)
end
parse(yaml_hash, stack:, context: nil) click to toggle source
# File lib/structured/struct.rb, line 72
def parse(yaml_hash, stack:, context: nil)
  parsed_instance = new
  parse_attributes(yaml_hash || {}, stack: stack, context: context).each do |attribute, value|
    parsed_instance.send(:"#{attribute}=", value)
  end

  parsed_instance
end
required_attribute(name, type) click to toggle source
# File lib/structured/struct.rb, line 57
def required_attribute(name, type)
  define_accessor(name.to_s)
  attributes[name.to_s] = Attribute.new(self, type)
end

Protected Instance Methods

attribute_accessors_module() click to toggle source
# File lib/structured/struct.rb, line 110
def attribute_accessors_module
  self::AttributeAccessors ||= begin
    mod = Module.new
    include(mod)
    mod
  end
end
define_accessor(name) click to toggle source
# File lib/structured/struct.rb, line 96
def define_accessor(name)
  attribute_accessors_module.send(:define_method, name) do
    read_attribute(name)
  end

  attribute_accessors_module.send(:define_method, "#{name}?") do
    has_attribute?(name)
  end

  attribute_accessors_module.send(:define_method, "#{name}=") do |value|
    write_attribute(name, value)
  end
end
parse_attributes(yaml_hash, allow_unknowns: false, stack:, context:) click to toggle source
# File lib/structured/struct.rb, line 118
def parse_attributes(yaml_hash, allow_unknowns: false, stack:, context:)
  unless yaml_hash.is_a?(Hash)
    raise Structured::Errors::InvalidValue.new(stack,
      "#{stack} expects a hash, but found #{yaml_hash.class.name}")
  end

  result = {}
  errors = []
  attributes.each do |name, attribute|
    begin
      next if attribute == :ignore

      if yaml_hash.key?(name)
        result[name.to_sym] = attribute.type.parse(yaml_hash[name],
          stack: stack.push(name, attribute.type), context: context)
      elsif !attribute.has_default?
        raise Structured::Errors::MissingKey.new(stack,
          "#{stack} (#{type_name}) requires the following key: #{name}")
      end
    rescue Structured::Errors::Base => exception
      errors << exception
    end
  end

  unknown_keys = yaml_hash.keys - attributes.keys.map(&:to_s)
  unless allow_unknowns || unknown_keys.empty?
    unknown_keys.each do |key|
      errors << Structured::Errors::UnknownKey.new(stack,
        "#{stack} (#{type_name}) does not support a #{key} field")
    end
  end

  raise Structured::Errors::MultipleErrors.union(stack, errors) unless errors.empty?
  result
end