module Lutaml::Model::Serialize

def self.included(base)

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

def attr_value(attrs, name, attr_rule)

def attr_value(attrs, name, attr_rule)
  value = if attrs.key?(name.to_sym)
            attrs[name.to_sym]
          elsif attrs.key?(name.to_s)
            attrs[name.to_s]
          else
            attr_rule.default
          end
  if attr_rule.collection? || value.is_a?(Array)
    (value || []).map do |v|
      if v.is_a?(Hash)
        attr_rule.type.new(v)
      else
        # TODO: This code is problematic because Type.cast does not know
        # about all the types.
        Lutaml::Model::Type.cast(v, attr_rule.type)
      end
    end
  else
    # TODO: This code is problematic because Type.cast does not know
    # about all the types.
    Lutaml::Model::Type.cast(value, attr_rule.type)
  end
end

def initialize(attrs = {})

def initialize(attrs = {})
  @using_default = {}
  return unless self.class.attributes
  if attrs.is_a?(Lutaml::Model::MappingHash)
    @ordered = attrs.ordered?
    @element_order = attrs.item_order
  end
  if attrs.key?(:schema_location)
    self.schema_location = attrs[:schema_location]
  end
  self.class.attributes.each do |name, attr|
    value = if attrs.key?(name) || attrs.key?(name.to_s)
              attr_value(attrs, name, attr)
            else
              using_default_for(name)
              attr.default
            end
    # Initialize collections with an empty array if no value is provided
    if attr.collection? && value.nil?
      value = []
    end
    default = using_default?(name)
    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?("=") && self.class.attributes.key?(method_name.to_s.chomp("=").to_sym)
    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]).sort
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 value_set_for(attribute_name)

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