lib/lutaml/model/serialize.rb in lutaml-model-0.3.9 vs lib/lutaml/model/serialize.rb in lutaml-model-0.3.10
- old
+ new
@@ -7,15 +7,18 @@
require_relative "mapping_hash"
require_relative "xml_mapping"
require_relative "key_value_mapping"
require_relative "json_adapter"
require_relative "comparable_model"
+require_relative "schema_location"
+require_relative "validation"
module Lutaml
module Model
module Serialize
include ComparableModel
+ include Validation
def self.included(base)
base.extend(ClassMethods)
end
@@ -50,29 +53,14 @@
instance_variable_get(:"@#{name}")
end
define_method(:"#{name}=") do |value|
instance_variable_set(:"@#{name}", value)
- validate
+ # validate!(name)
end
end
- # Check if the value to be assigned is valid for the attribute
- def attr_value_valid?(name, value)
- attr = attributes[name]
-
- return true unless attr.options[:values]
-
- # Allow nil values if there's no default
- return true if value.nil? && !attr.default
-
- # Use the default value if the value is nil
- value = attr.default if value.nil?
-
- attr.options[:values].include?(value)
- end
-
Lutaml::Model::Config::AVAILABLE_FORMATS.each do |format|
define_method(format) do |&block|
klass = format == :xml ? XmlMapping : KeyValueMapping
mappings[format] = klass.new
mappings[format].instance_eval(&block)
@@ -90,12 +78,12 @@
end
define_method(:"of_#{format}") do |hash|
if hash.is_a?(Array)
return hash.map do |item|
- apply_mappings(item, format)
- end
+ apply_mappings(item, format)
+ end
end
apply_mappings(hash, format)
end
@@ -314,10 +302,18 @@
if instance.respond_to?(:ordered=) && doc.is_a?(Lutaml::Model::MappingHash)
instance.element_order = doc.item_order
instance.ordered = mappings_for(:xml).mixed_content? || options[:mixed_content]
end
+ if doc["__schema_location"]
+ instance.schema_location = Lutaml::Model::SchemaLocation.new(
+ schema_location: doc["__schema_location"][:schema_location],
+ prefix: doc["__schema_location"][:prefix],
+ namespace: doc["__schema_location"][:namespace],
+ )
+ end
+
mappings.each do |rule|
attr = attributes[rule.to]
raise "Attribute '#{rule.to}' not found in #{self}" unless attr
is_content_mapping = rule.name.nil?
@@ -374,29 +370,59 @@
value
end
end
end
- attr_accessor :element_order
+ attr_accessor :element_order, :schema_location
def initialize(attrs = {})
+ @validate_on_set = attrs.delete(:validate_on_set) || false
+
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 = self.class.attr_value(attrs, name, attr)
+ value = if attrs.key?(name) || attrs.key?(name.to_s)
+ self.class.attr_value(attrs, name, attr)
+ else
+ attr.default
+ end
- send(:"#{name}=", self.class.ensure_utf8(value))
+ # Initialize collections with an empty array if no value is provided
+ if attr.collection? && value.nil?
+ value = []
+ end
+
+ instance_variable_set(:"@#{name}", self.class.ensure_utf8(value))
end
+ end
- validate
+ 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 validate_attribute!(attr_name)
+ attr = self.class.attributes[attr_name]
+ value = instance_variable_get(:"@#{attr_name}")
+ attr.validate_value!(value)
+ end
+
def ordered?
@ordered
end
def ordered=(ordered)
@@ -411,29 +437,19 @@
hash[key.to_sym] || hash[key.to_s]
end
Lutaml::Model::Config::AVAILABLE_FORMATS.each do |format|
define_method(:"to_#{format}") do |options = {}|
- validate
+ validate!
adapter = Lutaml::Model::Config.public_send(:"#{format}_adapter")
representation = if format == :xml
self
else
self.class.hash_representation(self, format,
options)
end
adapter.new(representation).public_send(:"to_#{format}", options)
- end
- end
-
- def validate
- self.class.attributes.each do |name, attr|
- value = send(name)
- unless self.class.attr_value_valid?(name, value)
- raise Lutaml::Model::InvalidValueError.new(name, value,
- attr.options[:values])
- end
end
end
end
end
end