lutaml-model 0.3.1 → 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop.yml +0 -5
- data/.rubocop_todo.yml +20 -101
- data/Gemfile +3 -18
- data/README.adoc +109 -6
- data/lib/lutaml/model/attribute.rb +15 -2
- data/lib/lutaml/model/config.rb +0 -1
- data/lib/lutaml/model/json_adapter/json_document.rb +20 -0
- data/lib/lutaml/model/json_adapter/json_object.rb +28 -0
- data/lib/lutaml/model/json_adapter/{multi_json.rb → multi_json_adapter.rb} +2 -3
- data/lib/lutaml/model/json_adapter/{standard.rb → standard_json_adapter.rb} +2 -3
- data/lib/lutaml/model/json_adapter.rb +1 -31
- data/lib/lutaml/model/key_value_mapping.rb +0 -1
- data/lib/lutaml/model/key_value_mapping_rule.rb +0 -1
- data/lib/lutaml/model/mapping_hash.rb +0 -2
- data/lib/lutaml/model/mapping_rule.rb +0 -1
- data/lib/lutaml/model/schema/json_schema.rb +0 -1
- data/lib/lutaml/model/schema/relaxng_schema.rb +0 -1
- data/lib/lutaml/model/schema/xsd_schema.rb +0 -1
- data/lib/lutaml/model/schema/yaml_schema.rb +0 -1
- data/lib/lutaml/model/schema.rb +0 -1
- data/lib/lutaml/model/serializable.rb +0 -1
- data/lib/lutaml/model/serialize.rb +22 -4
- data/lib/lutaml/model/toml_adapter/toml_document.rb +20 -0
- data/lib/lutaml/model/toml_adapter/toml_object.rb +28 -0
- data/lib/lutaml/model/toml_adapter/toml_rb_adapter.rb +2 -3
- data/lib/lutaml/model/toml_adapter/tomlib_adapter.rb +2 -3
- data/lib/lutaml/model/toml_adapter.rb +0 -31
- data/lib/lutaml/model/type/date_time.rb +20 -0
- data/lib/lutaml/model/type/json.rb +34 -0
- data/lib/lutaml/model/type/time_without_date.rb +4 -3
- data/lib/lutaml/model/type.rb +61 -124
- data/lib/lutaml/model/version.rb +1 -1
- data/lib/lutaml/model/xml_adapter/nokogiri_adapter.rb +5 -6
- data/lib/lutaml/model/xml_adapter/oga_adapter.rb +4 -5
- data/lib/lutaml/model/xml_adapter/ox_adapter.rb +8 -9
- data/lib/lutaml/model/xml_adapter/xml_attribute.rb +27 -0
- data/lib/lutaml/model/xml_adapter/xml_document.rb +184 -0
- data/lib/lutaml/model/xml_adapter/xml_element.rb +94 -0
- data/lib/lutaml/model/xml_adapter/xml_namespace.rb +49 -0
- data/lib/lutaml/model/xml_adapter.rb +0 -285
- data/lib/lutaml/model/xml_mapping.rb +1 -1
- data/lib/lutaml/model/xml_mapping_rule.rb +3 -4
- data/lib/lutaml/model/yaml_adapter/standard_yaml_adapter.rb +34 -0
- data/lib/lutaml/model/yaml_adapter/yaml_document.rb +20 -0
- data/lib/lutaml/model/yaml_adapter/yaml_object.rb +28 -0
- data/lib/lutaml/model/yaml_adapter.rb +1 -27
- data/lib/lutaml/model.rb +0 -5
- metadata +17 -5
- data/lib/lutaml/model/xml_namespace.rb +0 -47
| @@ -1,4 +1,3 @@ | |
| 1 | 
            -
            # lib/lutaml/model/serialize.rb
         | 
| 2 1 | 
             
            require_relative "yaml_adapter"
         | 
| 3 2 | 
             
            require_relative "xml_adapter"
         | 
| 4 3 | 
             
            require_relative "config"
         | 
| @@ -41,6 +40,7 @@ module Lutaml | |
| 41 40 | 
             
                      end
         | 
| 42 41 | 
             
                    end
         | 
| 43 42 |  | 
| 43 | 
            +
                    # Define an attribute for the model
         | 
| 44 44 | 
             
                    def attribute(name, type, options = {})
         | 
| 45 45 | 
             
                      attr = Attribute.new(name, type, options)
         | 
| 46 46 | 
             
                      attributes[name] = attr
         | 
| @@ -50,7 +50,7 @@ module Lutaml | |
| 50 50 | 
             
                      end
         | 
| 51 51 |  | 
| 52 52 | 
             
                      define_method(:"#{name}=") do |value|
         | 
| 53 | 
            -
                         | 
| 53 | 
            +
                        unless self.class.attr_value_valid?(name, value)
         | 
| 54 54 | 
             
                          raise Lutaml::Model::InvalidValueError.new(name, value, options[:values])
         | 
| 55 55 | 
             
                        end
         | 
| 56 56 |  | 
| @@ -58,6 +58,17 @@ module Lutaml | |
| 58 58 | 
             
                      end
         | 
| 59 59 | 
             
                    end
         | 
| 60 60 |  | 
| 61 | 
            +
                    # Check if the value to be assigned is valid for the attribute
         | 
| 62 | 
            +
                    def attr_value_valid?(name, value)
         | 
| 63 | 
            +
                      attr = attributes[name]
         | 
| 64 | 
            +
             | 
| 65 | 
            +
                      return true unless attr.options[:values]
         | 
| 66 | 
            +
             | 
| 67 | 
            +
                      # If value validation failed but there is a default value, do not
         | 
| 68 | 
            +
                      # raise a validation error
         | 
| 69 | 
            +
                      attr.options[:values].include?(value || attr.default)
         | 
| 70 | 
            +
                    end
         | 
| 71 | 
            +
             | 
| 61 72 | 
             
                    FORMATS.each do |format|
         | 
| 62 73 | 
             
                      define_method(format) do |&block|
         | 
| 63 74 | 
             
                        klass = format == :xml ? XmlMapping : KeyValueMapping
         | 
| @@ -193,6 +204,8 @@ module Lutaml | |
| 193 204 | 
             
                          if v.is_a?(Hash)
         | 
| 194 205 | 
             
                            attr_rule.type.new(v)
         | 
| 195 206 | 
             
                          else
         | 
| 207 | 
            +
                            # TODO: This code is problematic because Type.cast does not know
         | 
| 208 | 
            +
                            # about all the types.
         | 
| 196 209 | 
             
                            Lutaml::Model::Type.cast(
         | 
| 197 210 | 
             
                              v, attr_rule.type
         | 
| 198 211 | 
             
                            )
         | 
| @@ -201,6 +214,8 @@ module Lutaml | |
| 201 214 | 
             
                      elsif value.is_a?(Hash) && attr_rule.type != Lutaml::Model::Type::Hash
         | 
| 202 215 | 
             
                        generate_model_object(attr_rule.type, value)
         | 
| 203 216 | 
             
                      else
         | 
| 217 | 
            +
                        # TODO: This code is problematic because Type.cast does not know
         | 
| 218 | 
            +
                        # about all the types.
         | 
| 204 219 | 
             
                        Lutaml::Model::Type.cast(value, attr_rule.type)
         | 
| 205 220 | 
             
                      end
         | 
| 206 221 | 
             
                    end
         | 
| @@ -209,8 +224,11 @@ module Lutaml | |
| 209 224 | 
             
                      klass = format == :xml ? XmlMapping : KeyValueMapping
         | 
| 210 225 | 
             
                      klass.new.tap do |mapping|
         | 
| 211 226 | 
             
                        attributes&.each do |name, attr|
         | 
| 212 | 
            -
                          mapping.map_element( | 
| 213 | 
            -
             | 
| 227 | 
            +
                          mapping.map_element(
         | 
| 228 | 
            +
                            name.to_s,
         | 
| 229 | 
            +
                            to: name,
         | 
| 230 | 
            +
                            render_nil: attr.render_nil?,
         | 
| 231 | 
            +
                          )
         | 
| 214 232 | 
             
                        end
         | 
| 215 233 | 
             
                      end
         | 
| 216 234 | 
             
                    end
         | 
| @@ -0,0 +1,20 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require_relative "toml_object"
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            module Lutaml
         | 
| 6 | 
            +
              module Model
         | 
| 7 | 
            +
                module TomlAdapter
         | 
| 8 | 
            +
                  # Base class for TOML documents
         | 
| 9 | 
            +
                  class TomlDocument < TomlObject
         | 
| 10 | 
            +
                    def self.parse(toml)
         | 
| 11 | 
            +
                      raise NotImplementedError, "Subclasses must implement `parse`."
         | 
| 12 | 
            +
                    end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                    def to_toml(*args)
         | 
| 15 | 
            +
                      raise NotImplementedError, "Subclasses must implement `to_toml`."
         | 
| 16 | 
            +
                    end
         | 
| 17 | 
            +
                  end
         | 
| 18 | 
            +
                end
         | 
| 19 | 
            +
              end
         | 
| 20 | 
            +
            end
         | 
| @@ -0,0 +1,28 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Lutaml
         | 
| 4 | 
            +
              module Model
         | 
| 5 | 
            +
                module TomlAdapter
         | 
| 6 | 
            +
                  # Base class for TOML objects
         | 
| 7 | 
            +
                  class TomlObject
         | 
| 8 | 
            +
                    attr_reader :attributes
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                    def initialize(attributes = {})
         | 
| 11 | 
            +
                      @attributes = attributes
         | 
| 12 | 
            +
                    end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                    def [](key)
         | 
| 15 | 
            +
                      @attributes[key]
         | 
| 16 | 
            +
                    end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                    def []=(key, value)
         | 
| 19 | 
            +
                      @attributes[key] = value
         | 
| 20 | 
            +
                    end
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                    def to_h
         | 
| 23 | 
            +
                      @attributes
         | 
| 24 | 
            +
                    end
         | 
| 25 | 
            +
                  end
         | 
| 26 | 
            +
                end
         | 
| 27 | 
            +
              end
         | 
| 28 | 
            +
            end
         | 
| @@ -1,11 +1,10 @@ | |
| 1 | 
            -
            # lib/lutaml/model/toml_adapter/toml_rb_adapter.rb
         | 
| 2 1 | 
             
            require "toml-rb"
         | 
| 3 | 
            -
            require_relative " | 
| 2 | 
            +
            require_relative "toml_document"
         | 
| 4 3 |  | 
| 5 4 | 
             
            module Lutaml
         | 
| 6 5 | 
             
              module Model
         | 
| 7 6 | 
             
                module TomlAdapter
         | 
| 8 | 
            -
                  class  | 
| 7 | 
            +
                  class TomlRbAdapter < TomlDocument
         | 
| 9 8 | 
             
                    def self.parse(toml)
         | 
| 10 9 | 
             
                      data = TomlRB.parse(toml)
         | 
| 11 10 | 
             
                      new(data)
         | 
| @@ -1,11 +1,10 @@ | |
| 1 | 
            -
            # lib/lutaml/model/toml_adapter/tomlib_adapter.rb
         | 
| 2 1 | 
             
            require "tomlib"
         | 
| 3 | 
            -
            require_relative " | 
| 2 | 
            +
            require_relative "toml_document"
         | 
| 4 3 |  | 
| 5 4 | 
             
            module Lutaml
         | 
| 6 5 | 
             
              module Model
         | 
| 7 6 | 
             
                module TomlAdapter
         | 
| 8 | 
            -
                  class  | 
| 7 | 
            +
                  class TomlibAdapter < TomlDocument
         | 
| 9 8 | 
             
                    def self.parse(toml)
         | 
| 10 9 | 
             
                      data = Tomlib.load(toml)
         | 
| 11 10 | 
             
                      new(data)
         | 
| @@ -1,37 +1,6 @@ | |
| 1 | 
            -
            # lib/lutaml/model/toml_adapter.rb
         | 
| 2 | 
            -
             | 
| 3 1 | 
             
            module Lutaml
         | 
| 4 2 | 
             
              module Model
         | 
| 5 3 | 
             
                module TomlAdapter
         | 
| 6 | 
            -
                  class TomlObject
         | 
| 7 | 
            -
                    attr_reader :attributes
         | 
| 8 | 
            -
             | 
| 9 | 
            -
                    def initialize(attributes = {})
         | 
| 10 | 
            -
                      @attributes = attributes
         | 
| 11 | 
            -
                    end
         | 
| 12 | 
            -
             | 
| 13 | 
            -
                    def [](key)
         | 
| 14 | 
            -
                      @attributes[key]
         | 
| 15 | 
            -
                    end
         | 
| 16 | 
            -
             | 
| 17 | 
            -
                    def []=(key, value)
         | 
| 18 | 
            -
                      @attributes[key] = value
         | 
| 19 | 
            -
                    end
         | 
| 20 | 
            -
             | 
| 21 | 
            -
                    def to_h
         | 
| 22 | 
            -
                      @attributes
         | 
| 23 | 
            -
                    end
         | 
| 24 | 
            -
                  end
         | 
| 25 | 
            -
             | 
| 26 | 
            -
                  class Document < TomlObject
         | 
| 27 | 
            -
                    def self.parse(toml)
         | 
| 28 | 
            -
                      raise NotImplementedError, "Subclasses must implement `parse`."
         | 
| 29 | 
            -
                    end
         | 
| 30 | 
            -
             | 
| 31 | 
            -
                    def to_toml(*args)
         | 
| 32 | 
            -
                      raise NotImplementedError, "Subclasses must implement `to_toml`."
         | 
| 33 | 
            -
                    end
         | 
| 34 | 
            -
                  end
         | 
| 35 4 | 
             
                end
         | 
| 36 5 | 
             
              end
         | 
| 37 6 | 
             
            end
         | 
| @@ -0,0 +1,20 @@ | |
| 1 | 
            +
            require "date"
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Lutaml
         | 
| 4 | 
            +
              module Model
         | 
| 5 | 
            +
                module Type
         | 
| 6 | 
            +
                  # Date and time representation
         | 
| 7 | 
            +
                  class DateTime
         | 
| 8 | 
            +
                    def self.cast(value)
         | 
| 9 | 
            +
                      return if value.nil?
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                      ::DateTime.parse(value.to_s).new_offset(0)
         | 
| 12 | 
            +
                    end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                    def self.serialize(value)
         | 
| 15 | 
            +
                      value.iso8601
         | 
| 16 | 
            +
                    end
         | 
| 17 | 
            +
                  end
         | 
| 18 | 
            +
                end
         | 
| 19 | 
            +
              end
         | 
| 20 | 
            +
            end
         | 
| @@ -0,0 +1,34 @@ | |
| 1 | 
            +
            require "json"
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Lutaml
         | 
| 4 | 
            +
              module Model
         | 
| 5 | 
            +
                module Type
         | 
| 6 | 
            +
                  # JSON representation
         | 
| 7 | 
            +
                  class Json
         | 
| 8 | 
            +
                    attr_reader :value
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                    def initialize(value)
         | 
| 11 | 
            +
                      @value = value
         | 
| 12 | 
            +
                    end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                    def to_json(*_args)
         | 
| 15 | 
            +
                      @value.to_json
         | 
| 16 | 
            +
                    end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                    def ==(other)
         | 
| 19 | 
            +
                      @value == (other.is_a?(::Hash) ? other : other.value)
         | 
| 20 | 
            +
                    end
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                    def self.cast(value)
         | 
| 23 | 
            +
                      return value if value.is_a?(self) || value.nil?
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                      new(::JSON.parse(value))
         | 
| 26 | 
            +
                    end
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                    def self.serialize(value)
         | 
| 29 | 
            +
                      value.to_json
         | 
| 30 | 
            +
                    end
         | 
| 31 | 
            +
                  end
         | 
| 32 | 
            +
                end
         | 
| 33 | 
            +
              end
         | 
| 34 | 
            +
            end
         | 
| @@ -1,11 +1,12 @@ | |
| 1 | 
            -
            # lib/lutaml/model/type/time_without_date.rb
         | 
| 2 1 | 
             
            module Lutaml
         | 
| 3 2 | 
             
              module Model
         | 
| 4 3 | 
             
                module Type
         | 
| 4 | 
            +
                  # Time representation without date
         | 
| 5 5 | 
             
                  class TimeWithoutDate
         | 
| 6 6 | 
             
                    def self.cast(value)
         | 
| 7 | 
            -
                       | 
| 8 | 
            -
             | 
| 7 | 
            +
                      return if value.nil?
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                      ::Time.parse(value.to_s)
         | 
| 9 10 | 
             
                    end
         | 
| 10 11 |  | 
| 11 12 | 
             
                    def self.serialize(value)
         | 
    
        data/lib/lutaml/model/type.rb
    CHANGED
    
    | @@ -1,170 +1,97 @@ | |
| 1 | 
            -
            # lib/lutaml/model/type.rb
         | 
| 2 1 | 
             
            require "date"
         | 
| 3 2 | 
             
            require "bigdecimal"
         | 
| 4 3 | 
             
            require "securerandom"
         | 
| 5 4 | 
             
            require "uri"
         | 
| 6 5 | 
             
            require "ipaddr"
         | 
| 7 | 
            -
            require "json"
         | 
| 8 6 |  | 
| 9 7 | 
             
            module Lutaml
         | 
| 10 8 | 
             
              module Model
         | 
| 11 9 | 
             
                module Type
         | 
| 12 | 
            -
                   | 
| 13 | 
            -
             | 
| 14 | 
            -
             | 
| 15 | 
            -
             | 
| 16 | 
            -
             | 
| 17 | 
            -
             | 
| 18 | 
            -
             | 
| 19 | 
            -
             | 
| 20 | 
            -
             | 
| 21 | 
            -
             | 
| 22 | 
            -
             | 
| 23 | 
            -
             | 
| 24 | 
            -
             | 
| 25 | 
            -
             | 
| 26 | 
            -
             | 
| 27 | 
            -
             | 
| 28 | 
            -
             | 
| 10 | 
            +
                  # This module provides a set of methods to cast and serialize values
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                  # TODO: Make Boolean a separate class
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                  %w(
         | 
| 15 | 
            +
                    String
         | 
| 16 | 
            +
                    Integer
         | 
| 17 | 
            +
                    Float
         | 
| 18 | 
            +
                    Date
         | 
| 19 | 
            +
                    Time
         | 
| 20 | 
            +
                    Boolean
         | 
| 21 | 
            +
                    Decimal
         | 
| 22 | 
            +
                    Hash
         | 
| 23 | 
            +
                    Uuid
         | 
| 24 | 
            +
                    Symbol
         | 
| 25 | 
            +
                    Binary
         | 
| 26 | 
            +
                    Url
         | 
| 27 | 
            +
                    IpAddress
         | 
| 28 | 
            +
                    Json
         | 
| 29 | 
            +
                  ).each do |t|
         | 
| 29 30 | 
             
                    class_eval <<~HEREDOC, __FILE__, __LINE__ + 1
         | 
| 30 | 
            -
             | 
| 31 | 
            +
                                 class #{t}                        # class Integer
         | 
| 31 32 | 
             
                        def self.cast(value)            #   def self.cast(value)
         | 
| 32 33 | 
             
                          return if value.nil?          #     return if value.nil?
         | 
| 33 | 
            -
             | 
| 34 34 | 
             
                          Type.cast(value, #{t})        #     Type.cast(value, Integer)
         | 
| 35 35 | 
             
                        end                             #   end
         | 
| 36 36 |  | 
| 37 37 | 
             
                        def self.serialize(value)       #   def self.serialize(value)
         | 
| 38 38 | 
             
                          return if value.nil?          #     return if value.nil?
         | 
| 39 | 
            -
             | 
| 40 39 | 
             
                          Type.serialize(value, #{t})   #     Type.serialize(value, Integer)
         | 
| 41 40 | 
             
                        end                             #   end
         | 
| 42 41 | 
             
                      end                               # end
         | 
| 43 42 | 
             
                    HEREDOC
         | 
| 44 43 | 
             
                  end
         | 
| 45 44 |  | 
| 46 | 
            -
                   | 
| 47 | 
            -
             | 
| 48 | 
            -
                      return if value.nil?
         | 
| 49 | 
            -
             | 
| 50 | 
            -
                      ::Time.parse(value.to_s)
         | 
| 51 | 
            -
                      # .strftime("%H:%M:%S")
         | 
| 52 | 
            -
                    end
         | 
| 53 | 
            -
             | 
| 54 | 
            -
                    def self.serialize(value)
         | 
| 55 | 
            -
                      value.strftime("%H:%M:%S")
         | 
| 56 | 
            -
                    end
         | 
| 57 | 
            -
                  end
         | 
| 58 | 
            -
             | 
| 59 | 
            -
                  class DateTime
         | 
| 60 | 
            -
                    def self.cast(value)
         | 
| 61 | 
            -
                      return if value.nil?
         | 
| 62 | 
            -
             | 
| 63 | 
            -
                      ::DateTime.parse(value.to_s).new_offset(0)
         | 
| 64 | 
            -
                    end
         | 
| 65 | 
            -
             | 
| 66 | 
            -
                    def self.serialize(value)
         | 
| 67 | 
            -
                      value.iso8601
         | 
| 68 | 
            -
                    end
         | 
| 69 | 
            -
                  end
         | 
| 70 | 
            -
             | 
| 45 | 
            +
                  # TODO: Remove this. The XSD code depends on this but actually should
         | 
| 46 | 
            +
                  # be converted into a collection, not a specific Array type.
         | 
| 71 47 | 
             
                  class Array
         | 
| 72 48 | 
             
                    def initialize(array)
         | 
| 73 49 | 
             
                      Array(array)
         | 
| 74 50 | 
             
                    end
         | 
| 75 51 | 
             
                  end
         | 
| 76 52 |  | 
| 77 | 
            -
                  class TextWithTags
         | 
| 78 | 
            -
                    attr_reader :content
         | 
| 79 | 
            -
             | 
| 80 | 
            -
                    def initialize(ordered_text_with_tags)
         | 
| 81 | 
            -
                      @content = ordered_text_with_tags
         | 
| 82 | 
            -
                    end
         | 
| 83 | 
            -
             | 
| 84 | 
            -
                    def self.cast(value)
         | 
| 85 | 
            -
                      return value if value.is_a?(self)
         | 
| 86 | 
            -
             | 
| 87 | 
            -
                      new(value)
         | 
| 88 | 
            -
                    end
         | 
| 89 | 
            -
             | 
| 90 | 
            -
                    def self.serialize(value)
         | 
| 91 | 
            -
                      value.content.join
         | 
| 92 | 
            -
                    end
         | 
| 93 | 
            -
                  end
         | 
| 94 | 
            -
             | 
| 95 | 
            -
                  class JSON
         | 
| 96 | 
            -
                    attr_reader :value
         | 
| 97 | 
            -
             | 
| 98 | 
            -
                    def initialize(value)
         | 
| 99 | 
            -
                      @value = value
         | 
| 100 | 
            -
                    end
         | 
| 101 | 
            -
             | 
| 102 | 
            -
                    def to_json(*_args)
         | 
| 103 | 
            -
                      @value.to_json
         | 
| 104 | 
            -
                    end
         | 
| 105 | 
            -
             | 
| 106 | 
            -
                    def ==(other)
         | 
| 107 | 
            -
                      @value == if other.is_a?(::Hash)
         | 
| 108 | 
            -
                                  other
         | 
| 109 | 
            -
                                else
         | 
| 110 | 
            -
                                  other.value
         | 
| 111 | 
            -
                                end
         | 
| 112 | 
            -
                    end
         | 
| 113 | 
            -
             | 
| 114 | 
            -
                    def self.cast(value)
         | 
| 115 | 
            -
                      return value if value.is_a?(self) || value.nil?
         | 
| 116 | 
            -
             | 
| 117 | 
            -
                      new(::JSON.parse(value))
         | 
| 118 | 
            -
                    end
         | 
| 119 | 
            -
             | 
| 120 | 
            -
                    def self.serialize(value)
         | 
| 121 | 
            -
                      value.to_json
         | 
| 122 | 
            -
                    end
         | 
| 123 | 
            -
                  end
         | 
| 124 | 
            -
             | 
| 125 53 | 
             
                  UUID_REGEX = /\A[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}\z/
         | 
| 126 54 |  | 
| 127 55 | 
             
                  def self.cast(value, type)
         | 
| 128 56 | 
             
                    return if value.nil?
         | 
| 129 57 |  | 
| 130 | 
            -
                     | 
| 58 | 
            +
                    case type.to_s.split("::").last
         | 
| 59 | 
            +
                    when "String"
         | 
| 131 60 | 
             
                      value.to_s
         | 
| 132 | 
            -
                     | 
| 61 | 
            +
                    when "Integer"
         | 
| 133 62 | 
             
                      value.to_i
         | 
| 134 | 
            -
                     | 
| 63 | 
            +
                    when "Float"
         | 
| 135 64 | 
             
                      value.to_f
         | 
| 136 | 
            -
                     | 
| 65 | 
            +
                    when "Date"
         | 
| 137 66 | 
             
                      begin
         | 
| 138 67 | 
             
                        ::Date.parse(value.to_s)
         | 
| 139 68 | 
             
                      rescue ArgumentError
         | 
| 140 69 | 
             
                        nil
         | 
| 141 70 | 
             
                      end
         | 
| 142 | 
            -
                     | 
| 71 | 
            +
                    when "DateTime"
         | 
| 143 72 | 
             
                      DateTime.cast(value)
         | 
| 144 | 
            -
                     | 
| 73 | 
            +
                    when "Time"
         | 
| 145 74 | 
             
                      ::Time.parse(value.to_s)
         | 
| 146 | 
            -
                     | 
| 75 | 
            +
                    when "TimeWithoutDate"
         | 
| 147 76 | 
             
                      TimeWithoutDate.cast(value)
         | 
| 148 | 
            -
                     | 
| 77 | 
            +
                    when "Boolean"
         | 
| 149 78 | 
             
                      to_boolean(value)
         | 
| 150 | 
            -
                     | 
| 79 | 
            +
                    when "Decimal"
         | 
| 151 80 | 
             
                      BigDecimal(value.to_s)
         | 
| 152 | 
            -
                     | 
| 81 | 
            +
                    when "Hash"
         | 
| 153 82 | 
             
                      normalize_hash(Hash(value))
         | 
| 154 | 
            -
                     | 
| 83 | 
            +
                    when "Uuid"
         | 
| 155 84 | 
             
                      UUID_REGEX.match?(value) ? value : SecureRandom.uuid
         | 
| 156 | 
            -
                     | 
| 85 | 
            +
                    when "Symbol"
         | 
| 157 86 | 
             
                      value.to_sym
         | 
| 158 | 
            -
                     | 
| 87 | 
            +
                    when "Binary"
         | 
| 159 88 | 
             
                      value.force_encoding("BINARY")
         | 
| 160 | 
            -
                     | 
| 89 | 
            +
                    when "Url"
         | 
| 161 90 | 
             
                      URI.parse(value.to_s)
         | 
| 162 | 
            -
                     | 
| 91 | 
            +
                    when "IpAddress"
         | 
| 163 92 | 
             
                      IPAddr.new(value.to_s)
         | 
| 164 | 
            -
                     | 
| 165 | 
            -
                       | 
| 166 | 
            -
                    # elsif type == Enum
         | 
| 167 | 
            -
                    #   value
         | 
| 93 | 
            +
                    when "Json"
         | 
| 94 | 
            +
                      Json.cast(value)
         | 
| 168 95 | 
             
                    else
         | 
| 169 96 | 
             
                      value
         | 
| 170 97 | 
             
                    end
         | 
| @@ -173,21 +100,22 @@ module Lutaml | |
| 173 100 | 
             
                  def self.serialize(value, type)
         | 
| 174 101 | 
             
                    return if value.nil?
         | 
| 175 102 |  | 
| 176 | 
            -
                     | 
| 103 | 
            +
                    case type.to_s.split("::").last
         | 
| 104 | 
            +
                    when "Date"
         | 
| 177 105 | 
             
                      value.iso8601
         | 
| 178 | 
            -
                     | 
| 106 | 
            +
                    when "DateTime"
         | 
| 179 107 | 
             
                      DateTime.serialize(value)
         | 
| 180 | 
            -
                     | 
| 108 | 
            +
                    when "Integer"
         | 
| 181 109 | 
             
                      value.to_i
         | 
| 182 | 
            -
                     | 
| 110 | 
            +
                    when "Float"
         | 
| 183 111 | 
             
                      value.to_f
         | 
| 184 | 
            -
                     | 
| 112 | 
            +
                    when "Boolean"
         | 
| 185 113 | 
             
                      to_boolean(value)
         | 
| 186 | 
            -
                     | 
| 114 | 
            +
                    when "Decimal"
         | 
| 187 115 | 
             
                      value.to_s("F")
         | 
| 188 | 
            -
                     | 
| 116 | 
            +
                    when "Hash"
         | 
| 189 117 | 
             
                      Hash(value)
         | 
| 190 | 
            -
                     | 
| 118 | 
            +
                    when "Json"
         | 
| 191 119 | 
             
                      value.to_json
         | 
| 192 120 | 
             
                    else
         | 
| 193 121 | 
             
                      value.to_s
         | 
| @@ -195,8 +123,13 @@ module Lutaml | |
| 195 123 | 
             
                  end
         | 
| 196 124 |  | 
| 197 125 | 
             
                  def self.to_boolean(value)
         | 
| 198 | 
            -
                     | 
| 199 | 
            -
             | 
| 126 | 
            +
                    if value == true || value.to_s =~ (/^(true|t|yes|y|1)$/i)
         | 
| 127 | 
            +
                      return true
         | 
| 128 | 
            +
                    end
         | 
| 129 | 
            +
             | 
| 130 | 
            +
                    if value == false || value.nil? || value.to_s =~ (/^(false|f|no|n|0)$/i)
         | 
| 131 | 
            +
                      return false
         | 
| 132 | 
            +
                    end
         | 
| 200 133 |  | 
| 201 134 | 
             
                    raise ArgumentError.new("invalid value for Boolean: \"#{value}\"")
         | 
| 202 135 | 
             
                  end
         | 
| @@ -217,3 +150,7 @@ module Lutaml | |
| 217 150 | 
             
                end
         | 
| 218 151 | 
             
              end
         | 
| 219 152 | 
             
            end
         | 
| 153 | 
            +
             | 
| 154 | 
            +
            require_relative "type/time_without_date"
         | 
| 155 | 
            +
            require_relative "type/date_time"
         | 
| 156 | 
            +
            require_relative "type/json"
         | 
    
        data/lib/lutaml/model/version.rb
    CHANGED
    
    
| @@ -1,11 +1,10 @@ | |
| 1 | 
            -
            # lib/lutaml/model/xml_adapter/nokogiri_adapter.rb
         | 
| 2 1 | 
             
            require "nokogiri"
         | 
| 3 | 
            -
            require_relative " | 
| 2 | 
            +
            require_relative "xml_document"
         | 
| 4 3 |  | 
| 5 4 | 
             
            module Lutaml
         | 
| 6 5 | 
             
              module Model
         | 
| 7 6 | 
             
                module XmlAdapter
         | 
| 8 | 
            -
                  class  | 
| 7 | 
            +
                  class NokogiriAdapter < XmlDocument
         | 
| 9 8 | 
             
                    def self.parse(xml)
         | 
| 10 9 | 
             
                      parsed = Nokogiri::XML(xml)
         | 
| 11 10 | 
             
                      root = NokogiriElement.new(parsed.root)
         | 
| @@ -154,11 +153,11 @@ module Lutaml | |
| 154 153 | 
             
                    end
         | 
| 155 154 | 
             
                  end
         | 
| 156 155 |  | 
| 157 | 
            -
                  class NokogiriElement <  | 
| 156 | 
            +
                  class NokogiriElement < XmlElement
         | 
| 158 157 | 
             
                    def initialize(node, root_node: nil)
         | 
| 159 158 | 
             
                      if root_node
         | 
| 160 159 | 
             
                        node.namespaces.each do |prefix, name|
         | 
| 161 | 
            -
                          namespace =  | 
| 160 | 
            +
                          namespace = XmlNamespace.new(name, prefix)
         | 
| 162 161 |  | 
| 163 162 | 
             
                          root_node.add_namespace(namespace)
         | 
| 164 163 | 
             
                        end
         | 
| @@ -172,7 +171,7 @@ module Lutaml | |
| 172 171 | 
             
                                 attr.name
         | 
| 173 172 | 
             
                               end
         | 
| 174 173 |  | 
| 175 | 
            -
                        attributes[name] =  | 
| 174 | 
            +
                        attributes[name] = XmlAttribute.new(
         | 
| 176 175 | 
             
                          name,
         | 
| 177 176 | 
             
                          attr.value,
         | 
| 178 177 | 
             
                          namespace: attr.namespace&.href,
         | 
| @@ -1,11 +1,10 @@ | |
| 1 | 
            -
            # lib/lutaml/model/xml_adapter/oga_adapter.rb
         | 
| 2 1 | 
             
            require "oga"
         | 
| 3 | 
            -
            require_relative " | 
| 2 | 
            +
            require_relative "xml_document"
         | 
| 4 3 |  | 
| 5 4 | 
             
            module Lutaml
         | 
| 6 5 | 
             
              module Model
         | 
| 7 6 | 
             
                module XmlAdapter
         | 
| 8 | 
            -
                  class  | 
| 7 | 
            +
                  class OgaAdapter < XmlDocument
         | 
| 9 8 | 
             
                    def self.parse(xml)
         | 
| 10 9 | 
             
                      parsed = Oga.parse_xml(xml)
         | 
| 11 10 | 
             
                      root = OgaElement.new(parsed)
         | 
| @@ -51,10 +50,10 @@ module Lutaml | |
| 51 50 | 
             
                    end
         | 
| 52 51 | 
             
                  end
         | 
| 53 52 |  | 
| 54 | 
            -
                  class OgaElement <  | 
| 53 | 
            +
                  class OgaElement < XmlElement
         | 
| 55 54 | 
             
                    def initialize(node)
         | 
| 56 55 | 
             
                      attributes = node.attributes.each_with_object({}) do |attr, hash|
         | 
| 57 | 
            -
                        hash[attr.name] =  | 
| 56 | 
            +
                        hash[attr.name] = XmlAttribute.new(attr.name, attr.value)
         | 
| 58 57 | 
             
                      end
         | 
| 59 58 | 
             
                      super(node.name, attributes, parse_children(node), node.text)
         | 
| 60 59 | 
             
                    end
         | 
| @@ -1,11 +1,10 @@ | |
| 1 | 
            -
            # lib/lutaml/model/xml_adapter/ox_adapter.rb
         | 
| 2 1 | 
             
            require "ox"
         | 
| 3 | 
            -
            require_relative " | 
| 2 | 
            +
            require_relative "xml_document"
         | 
| 4 3 |  | 
| 5 4 | 
             
            module Lutaml
         | 
| 6 5 | 
             
              module Model
         | 
| 7 6 | 
             
                module XmlAdapter
         | 
| 8 | 
            -
                  class  | 
| 7 | 
            +
                  class OxAdapter < XmlDocument
         | 
| 9 8 | 
             
                    def self.parse(xml)
         | 
| 10 9 | 
             
                      parsed = Ox.parse(xml)
         | 
| 11 10 | 
             
                      root = OxElement.new(parsed)
         | 
| @@ -137,16 +136,16 @@ module Lutaml | |
| 137 136 | 
             
                    end
         | 
| 138 137 | 
             
                  end
         | 
| 139 138 |  | 
| 140 | 
            -
                  class OxElement <  | 
| 139 | 
            +
                  class OxElement < XmlElement
         | 
| 141 140 | 
             
                    def initialize(node, root_node: nil)
         | 
| 142 141 | 
             
                      if node.is_a?(String)
         | 
| 143 142 | 
             
                        super("text", {}, [], node, parent_document: root_node)
         | 
| 144 143 | 
             
                      else
         | 
| 145 144 | 
             
                        namespace_attributes(node.attributes).each do |(name, value)|
         | 
| 146 145 | 
             
                          if root_node
         | 
| 147 | 
            -
                            root_node.add_namespace( | 
| 146 | 
            +
                            root_node.add_namespace(XmlNamespace.new(value, name))
         | 
| 148 147 | 
             
                          else
         | 
| 149 | 
            -
                            add_namespace( | 
| 148 | 
            +
                            add_namespace(XmlNamespace.new(value, name))
         | 
| 150 149 | 
             
                          end
         | 
| 151 150 | 
             
                        end
         | 
| 152 151 |  | 
| @@ -156,11 +155,11 @@ module Lutaml | |
| 156 155 | 
             
                          namespace_prefix = name.to_s.split(":").first
         | 
| 157 156 | 
             
                          if (n = name.to_s.split(":")).length > 1
         | 
| 158 157 | 
             
                            namespace = (root_node || self).namespaces[namespace_prefix]&.uri
         | 
| 159 | 
            -
                            namespace ||=  | 
| 158 | 
            +
                            namespace ||= XML_NAMESPACE_URI
         | 
| 160 159 | 
             
                            prefix = n.first
         | 
| 161 160 | 
             
                          end
         | 
| 162 161 |  | 
| 163 | 
            -
                          hash[name.to_s] =  | 
| 162 | 
            +
                          hash[name.to_s] = XmlAttribute.new(
         | 
| 164 163 | 
             
                            name.to_s,
         | 
| 165 164 | 
             
                            value,
         | 
| 166 165 | 
             
                            namespace: namespace,
         | 
| @@ -173,7 +172,7 @@ module Lutaml | |
| 173 172 | 
             
                          attributes,
         | 
| 174 173 | 
             
                          parse_children(node, root_node: root_node || self),
         | 
| 175 174 | 
             
                          node.text,
         | 
| 176 | 
            -
                          parent_document: root_node
         | 
| 175 | 
            +
                          parent_document: root_node,
         | 
| 177 176 | 
             
                        )
         | 
| 178 177 | 
             
                      end
         | 
| 179 178 | 
             
                    end
         | 
| @@ -0,0 +1,27 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Lutaml
         | 
| 4 | 
            +
              module Model
         | 
| 5 | 
            +
                module XmlAdapter
         | 
| 6 | 
            +
                  # Represents an XML attribute
         | 
| 7 | 
            +
                  class XmlAttribute
         | 
| 8 | 
            +
                    attr_reader :name, :value, :namespace, :namespace_prefix
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                    def initialize(name, value, namespace: nil, namespace_prefix: nil)
         | 
| 11 | 
            +
                      @name = name
         | 
| 12 | 
            +
                      @value = value
         | 
| 13 | 
            +
                      @namespace = namespace
         | 
| 14 | 
            +
                      @namespace_prefix = namespace_prefix
         | 
| 15 | 
            +
                    end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                    def unprefixed_name
         | 
| 18 | 
            +
                      if namespace_prefix
         | 
| 19 | 
            +
                        name.split(":").last
         | 
| 20 | 
            +
                      else
         | 
| 21 | 
            +
                        name
         | 
| 22 | 
            +
                      end
         | 
| 23 | 
            +
                    end
         | 
| 24 | 
            +
                  end
         | 
| 25 | 
            +
                end
         | 
| 26 | 
            +
              end
         | 
| 27 | 
            +
            end
         |