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