module Lutaml::Model::Serialize

def self.included(base)

def self.included(base)
  base.extend(ClassMethods)
  base.initialize_attrs(base)
end

def self.register_format_mapping_method(format)

def self.register_format_mapping_method(format)
  method_name = format == :hash ? :hsh : format
  ::Lutaml::Model::Serialize::ClassMethods.define_method(method_name) do |&block|
    process_mapping(format, &block)
  end
end

def self.register_from_format_method(format)

def self.register_from_format_method(format)
  ClassMethods.define_method(:"from_#{format}") do |data, options = {}|
    from(format, data, options)
  end
  ClassMethods.define_method(:"of_#{format}") do |doc, options = {}|
    of(format, doc, options)
  end
end

def self.register_to_format_method(format)

def self.register_to_format_method(format)
  ClassMethods.define_method(:"to_#{format}") do |instance, options = {}|
    to(format, instance, options)
  end
  ClassMethods.define_method(:"as_#{format}") do |instance, options = {}|
    as(format, instance, options)
  end
  define_method(:"to_#{format}") do |options = {}|
    to_format(format, options)
  end
end

def attr_value(attrs, name, attribute)

def attr_value(attrs, name, attribute)
  value = Utils.fetch_str_or_sym(attrs, name, attribute.default(__register))
  attribute.cast_value(value, __register)
end

def attribute_exist?(name)

def attribute_exist?(name)
  name = name.to_s.chomp("=").to_sym if name.end_with?("=")
  self.class.attributes.key?(name)
end

def determine_value(attrs, name, attr)

def determine_value(attrs, name, attr)
  if attrs.key?(name) || attrs.key?(name.to_s)
    attr_value(attrs, name, attr)
  elsif attr.default_set?(__register)
    using_default_for(name)
    attr.default(__register)
  else
    Lutaml::Model::UninitializedClass.instance
  end
end

def extract_register_id(attrs, options)

def extract_register_id(attrs, options)
  register = attrs&.dig(:__register) || options&.dig(:register)
  self.class.extract_register_id(register)
end

def initialize(attrs = {}, options = {})

def initialize(attrs = {}, options = {})
  @using_default = {}
  return unless self.class.attributes
  @__register = extract_register_id(attrs, options)
  set_ordering(attrs)
  set_schema_location(attrs)
  initialize_attributes(attrs, options)
end

def initialize_attributes(attrs, options = {})

def initialize_attributes(attrs, options = {})
  self.class.attributes.each do |name, attr|
    next if attr.derived?
    value = determine_value(attrs, name, attr)
    default = using_default?(name)
    value = self.class.apply_value_map(value, value_map(options), attr)
    public_send(:"#{name}=", self.class.ensure_utf8(value))
    using_default_for(name) if default
  end
end

def key_exist?(hash, key)

def key_exist?(hash, key)
  hash.key?(key.to_sym) || hash.key?(key.to_s)
end

def key_value(hash, key)

def key_value(hash, key)
  hash[key.to_sym] || hash[key.to_s]
end

def method_missing(method_name, *args)

def method_missing(method_name, *args)
  if method_name.to_s.end_with?("=") && attribute_exist?(method_name)
    define_singleton_method(method_name) do |value|
      instance_variable_set(:"@#{method_name.to_s.chomp('=')}", value)
    end
    send(method_name, *args)
  else
    super
  end
end

def mixed?

def mixed?
  !!@mixed
end

def ordered?

def ordered?
  !!@ordered
end

def pretty_print_instance_variables

def pretty_print_instance_variables
  (instance_variables - %i[@using_default @__register]).sort
end

def respond_to_missing?(method_name, include_private = false)

def respond_to_missing?(method_name, include_private = false)
  (method_name.to_s.end_with?("=") && attribute_exist?(method_name)) ||
    super
end

def set_ordering(attrs)

def set_ordering(attrs)
  return unless attrs.respond_to?(:ordered?)
  @ordered = attrs.ordered?
  @element_order = attrs.item_order
end

def set_schema_location(attrs)

def set_schema_location(attrs)
  return unless attrs.key?(:schema_location)
  self.schema_location = attrs[:schema_location]
end

def to_format(format, options = {})

def to_format(format, options = {})
  validate_root_mapping!(format, options)
  options[:parse_encoding] = encoding if encoding
  self.class.to(format, self, options)
end

def to_yaml_hash

def to_yaml_hash
  self.class.as_yaml(self)
end

def using_default?(attribute_name)

def using_default?(attribute_name)
  @using_default[attribute_name]
end

def using_default_for(attribute_name)

def using_default_for(attribute_name)
  @using_default[attribute_name] = true
end

def validate_attribute!(attr_name)

def validate_attribute!(attr_name)
  attr = self.class.attributes[attr_name]
  value = instance_variable_get(:"@#{attr_name}")
  attr.validate_value!(value)
end

def validate_root_mapping!(format, options)

def validate_root_mapping!(format, options)
  return if format != :xml
  return if options[:collection] || self.class.root?
  raise Lutaml::Model::NoRootMappingError.new(self.class)
end

def value_map(options)

def value_map(options)
  {
    omitted: options[:omitted] || :nil,
    nil: options[:nil] || :nil,
    empty: options[:empty] || :empty,
  }
end

def value_set_for(attribute_name)

def value_set_for(attribute_name)
  @using_default[attribute_name] = false
end