lutaml-model 0.3.24 → 0.3.25
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_todo.yml +35 -16
- data/README.adoc +274 -28
- data/lib/lutaml/model/attribute.rb +18 -8
- data/lib/lutaml/model/error/type_error.rb +9 -0
- data/lib/lutaml/model/error/unknown_type_error.rb +9 -0
- data/lib/lutaml/model/error/validation_error.rb +0 -1
- data/lib/lutaml/model/error.rb +2 -0
- data/lib/lutaml/model/serialize.rb +6 -1
- data/lib/lutaml/model/type/boolean.rb +38 -0
- data/lib/lutaml/model/type/date.rb +35 -0
- data/lib/lutaml/model/type/date_time.rb +32 -4
- data/lib/lutaml/model/type/decimal.rb +42 -0
- data/lib/lutaml/model/type/float.rb +37 -0
- data/lib/lutaml/model/type/hash.rb +62 -0
- data/lib/lutaml/model/type/integer.rb +41 -0
- data/lib/lutaml/model/type/string.rb +49 -0
- data/lib/lutaml/model/type/time.rb +49 -0
- data/lib/lutaml/model/type/time_without_date.rb +37 -5
- data/lib/lutaml/model/type/value.rb +52 -0
- data/lib/lutaml/model/type.rb +50 -114
- data/lib/lutaml/model/version.rb +1 -1
- data/lib/lutaml/model/xml_adapter/builder/nokogiri.rb +5 -2
- data/lib/lutaml/model/xml_adapter/ox_adapter.rb +2 -1
- data/lib/lutaml/model/xml_adapter/xml_document.rb +0 -2
- data/lutaml-model.gemspec +1 -1
- data/spec/address_spec.rb +170 -0
- data/spec/fixtures/address.rb +33 -0
- data/spec/fixtures/person.rb +73 -0
- data/spec/fixtures/sample_model.rb +40 -0
- data/spec/fixtures/vase.rb +38 -0
- data/spec/fixtures/xml/special_char.xml +13 -0
- data/spec/lutaml/model/attribute_spec.rb +112 -0
- data/spec/lutaml/model/collection_spec.rb +299 -0
- data/spec/lutaml/model/comparable_model_spec.rb +106 -0
- data/spec/lutaml/model/custom_model_spec.rb +410 -0
- data/spec/lutaml/model/custom_serialization_spec.rb +170 -0
- data/spec/lutaml/model/defaults_spec.rb +221 -0
- data/spec/lutaml/model/delegation_spec.rb +340 -0
- data/spec/lutaml/model/inheritance_spec.rb +92 -0
- data/spec/lutaml/model/json_adapter_spec.rb +37 -0
- data/spec/lutaml/model/key_value_mapping_spec.rb +86 -0
- data/spec/lutaml/model/map_content_spec.rb +118 -0
- data/spec/lutaml/model/mixed_content_spec.rb +625 -0
- data/spec/lutaml/model/namespace_spec.rb +57 -0
- data/spec/lutaml/model/ordered_content_spec.rb +83 -0
- data/spec/lutaml/model/render_nil_spec.rb +138 -0
- data/spec/lutaml/model/schema/json_schema_spec.rb +79 -0
- data/spec/lutaml/model/schema/relaxng_schema_spec.rb +60 -0
- data/spec/lutaml/model/schema/xsd_schema_spec.rb +55 -0
- data/spec/lutaml/model/schema/yaml_schema_spec.rb +47 -0
- data/spec/lutaml/model/serializable_spec.rb +297 -0
- data/spec/lutaml/model/serializable_validation_spec.rb +85 -0
- data/spec/lutaml/model/simple_model_spec.rb +314 -0
- data/spec/lutaml/model/toml_adapter_spec.rb +39 -0
- data/spec/lutaml/model/type/boolean_spec.rb +54 -0
- data/spec/lutaml/model/type/date_spec.rb +118 -0
- data/spec/lutaml/model/type/date_time_spec.rb +127 -0
- data/spec/lutaml/model/type/decimal_spec.rb +125 -0
- data/spec/lutaml/model/type/float_spec.rb +191 -0
- data/spec/lutaml/model/type/hash_spec.rb +63 -0
- data/spec/lutaml/model/type/integer_spec.rb +145 -0
- data/spec/lutaml/model/type/string_spec.rb +150 -0
- data/spec/lutaml/model/type/time_spec.rb +142 -0
- data/spec/lutaml/model/type/time_without_date_spec.rb +125 -0
- data/spec/lutaml/model/type_spec.rb +276 -0
- data/spec/lutaml/model/utils_spec.rb +79 -0
- data/spec/lutaml/model/validation_spec.rb +83 -0
- data/spec/lutaml/model/with_child_mapping_spec.rb +174 -0
- data/spec/lutaml/model/xml_adapter/nokogiri_adapter_spec.rb +56 -0
- data/spec/lutaml/model/xml_adapter/oga_adapter_spec.rb +56 -0
- data/spec/lutaml/model/xml_adapter/ox_adapter_spec.rb +61 -0
- data/spec/lutaml/model/xml_adapter/xml_namespace_spec.rb +251 -0
- data/spec/lutaml/model/xml_adapter_spec.rb +178 -0
- data/spec/lutaml/model/xml_mapping_spec.rb +863 -0
- data/spec/lutaml/model/yaml_adapter_spec.rb +30 -0
- data/spec/lutaml/model_spec.rb +1 -0
- data/spec/person_spec.rb +161 -0
- data/spec/spec_helper.rb +33 -0
- metadata +66 -2
@@ -0,0 +1,35 @@
|
|
1
|
+
module Lutaml
|
2
|
+
module Model
|
3
|
+
module Type
|
4
|
+
class Date < Value
|
5
|
+
def self.cast(value)
|
6
|
+
return nil if value.nil?
|
7
|
+
|
8
|
+
case value
|
9
|
+
when ::DateTime, ::Time
|
10
|
+
value.to_date
|
11
|
+
when ::Date
|
12
|
+
value
|
13
|
+
else
|
14
|
+
::Date.parse(value.to_s)
|
15
|
+
end
|
16
|
+
rescue ArgumentError
|
17
|
+
nil
|
18
|
+
end
|
19
|
+
|
20
|
+
# xs:date format
|
21
|
+
def self.serialize(value)
|
22
|
+
return nil if value.nil?
|
23
|
+
|
24
|
+
value&.iso8601
|
25
|
+
end
|
26
|
+
|
27
|
+
# This is to handle where Ruby's YAML safe_load does not handle
|
28
|
+
# the Date/Time classes
|
29
|
+
def to_yaml
|
30
|
+
value&.iso8601.to_s
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -4,15 +4,43 @@ module Lutaml
|
|
4
4
|
module Model
|
5
5
|
module Type
|
6
6
|
# Date and time representation
|
7
|
-
class DateTime
|
7
|
+
class DateTime < Value
|
8
8
|
def self.cast(value)
|
9
|
-
return if value.nil?
|
9
|
+
return nil if value.nil?
|
10
10
|
|
11
|
-
|
11
|
+
case value
|
12
|
+
when ::DateTime then value
|
13
|
+
when ::Time then value.to_datetime
|
14
|
+
else ::DateTime.parse(value.to_s)
|
15
|
+
end
|
16
|
+
rescue ArgumentError
|
17
|
+
nil
|
12
18
|
end
|
13
19
|
|
14
20
|
def self.serialize(value)
|
15
|
-
value.
|
21
|
+
return nil if value.nil?
|
22
|
+
|
23
|
+
cast(value)&.iso8601
|
24
|
+
end
|
25
|
+
|
26
|
+
# xs:dateTime format (ISO8601 with timezone)
|
27
|
+
def to_xml
|
28
|
+
value&.iso8601
|
29
|
+
end
|
30
|
+
|
31
|
+
# RFC3339 (ISO8601 with timezone)
|
32
|
+
def to_json(*_args)
|
33
|
+
value&.iso8601
|
34
|
+
end
|
35
|
+
|
36
|
+
# YAML timestamp format (native)
|
37
|
+
def to_yaml
|
38
|
+
value&.iso8601
|
39
|
+
end
|
40
|
+
|
41
|
+
# TOML datetime format (RFC3339)
|
42
|
+
def to_toml
|
43
|
+
value&.iso8601
|
16
44
|
end
|
17
45
|
end
|
18
46
|
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Lutaml
|
2
|
+
module Model
|
3
|
+
module Type
|
4
|
+
class Decimal < Value
|
5
|
+
def self.cast(value)
|
6
|
+
return nil if value.nil?
|
7
|
+
|
8
|
+
check_dependencies!(value)
|
9
|
+
case value
|
10
|
+
when BigDecimal
|
11
|
+
# If already a BigDecimal, return as-is
|
12
|
+
value
|
13
|
+
else
|
14
|
+
# Convert to string first to handle various input types
|
15
|
+
BigDecimal(value.to_s)
|
16
|
+
end
|
17
|
+
rescue ArgumentError
|
18
|
+
nil
|
19
|
+
end
|
20
|
+
|
21
|
+
# # xs:decimal format
|
22
|
+
def self.serialize(value)
|
23
|
+
return nil if value.nil?
|
24
|
+
|
25
|
+
check_dependencies!(value)
|
26
|
+
value = cast(value)
|
27
|
+
value.to_s("F") # Use fixed-point notation to match test expectations
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.from_xml(value)
|
31
|
+
cast(value.text)
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.check_dependencies!(value)
|
35
|
+
unless defined?(BigDecimal)
|
36
|
+
raise TypeNotEnabledError.new("Decimal", value)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Lutaml
|
2
|
+
module Model
|
3
|
+
module Type
|
4
|
+
class Float < Value
|
5
|
+
def self.cast(value)
|
6
|
+
return nil if value.nil?
|
7
|
+
|
8
|
+
value.to_f
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.serialize(value)
|
12
|
+
return nil if value.nil?
|
13
|
+
|
14
|
+
cast(value)
|
15
|
+
end
|
16
|
+
|
17
|
+
# Instance methods for specific formats
|
18
|
+
# xs:float format
|
19
|
+
def to_xml
|
20
|
+
value.to_s
|
21
|
+
end
|
22
|
+
|
23
|
+
def to_yaml
|
24
|
+
value
|
25
|
+
end
|
26
|
+
|
27
|
+
def to_json(*_args)
|
28
|
+
value
|
29
|
+
end
|
30
|
+
|
31
|
+
def to_yaml
|
32
|
+
value
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module Lutaml
|
2
|
+
module Model
|
3
|
+
module Type
|
4
|
+
class Hash < Value
|
5
|
+
def self.cast(value)
|
6
|
+
return nil if value.nil?
|
7
|
+
|
8
|
+
hash = if value.respond_to?(:to_h)
|
9
|
+
value.to_h
|
10
|
+
else
|
11
|
+
Hash(value)
|
12
|
+
end
|
13
|
+
|
14
|
+
normalize_hash(hash)
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.normalize_hash(hash)
|
18
|
+
return hash["text"] if hash.keys == ["text"]
|
19
|
+
|
20
|
+
hash = hash.to_h if hash.is_a?(Lutaml::Model::MappingHash)
|
21
|
+
|
22
|
+
hash = hash.except("text")
|
23
|
+
|
24
|
+
hash.transform_values do |value|
|
25
|
+
if value.is_a?(::Hash)
|
26
|
+
# Only process if value is a Hash
|
27
|
+
nested = normalize_hash(value)
|
28
|
+
# Only include non-text nodes in nested hashes if it's a hash
|
29
|
+
nested.is_a?(::Hash) ? nested.except("text") : nested
|
30
|
+
else
|
31
|
+
value
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.serialize(value)
|
37
|
+
return nil if value.nil?
|
38
|
+
return value if value.is_a?(Hash)
|
39
|
+
|
40
|
+
value.respond_to?(:to_h) ? value.to_h : Hash(value)
|
41
|
+
end
|
42
|
+
|
43
|
+
# Format-specific serialization methods
|
44
|
+
def to_xml
|
45
|
+
value
|
46
|
+
end
|
47
|
+
|
48
|
+
def to_json(*_args)
|
49
|
+
value
|
50
|
+
end
|
51
|
+
|
52
|
+
def to_yaml
|
53
|
+
value
|
54
|
+
end
|
55
|
+
|
56
|
+
def to_toml
|
57
|
+
value
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Lutaml
|
2
|
+
module Model
|
3
|
+
module Type
|
4
|
+
class Integer < Value
|
5
|
+
def self.cast(value)
|
6
|
+
return nil if value.nil?
|
7
|
+
return 1 if value === true
|
8
|
+
return 0 if value === false
|
9
|
+
|
10
|
+
case value
|
11
|
+
when ::String
|
12
|
+
if value.match?(/^0[0-7]+$/) # Octal
|
13
|
+
value.to_i(8)
|
14
|
+
elsif value.match?(/^-?\d+(\.\d+)?(e-?\d+)?$/i) # Float/exponential
|
15
|
+
Float(value).to_i
|
16
|
+
else
|
17
|
+
begin
|
18
|
+
Integer(value, 10)
|
19
|
+
rescue StandardError
|
20
|
+
nil
|
21
|
+
end
|
22
|
+
end
|
23
|
+
else
|
24
|
+
begin
|
25
|
+
Integer(value)
|
26
|
+
rescue StandardError
|
27
|
+
nil
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# Override serialize to return Integer instead of String
|
33
|
+
def self.serialize(value)
|
34
|
+
return nil if value.nil?
|
35
|
+
|
36
|
+
cast(value)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module Lutaml
|
2
|
+
module Model
|
3
|
+
module Type
|
4
|
+
class String < Value
|
5
|
+
def self.cast(value)
|
6
|
+
return nil if value.nil?
|
7
|
+
|
8
|
+
value.to_s
|
9
|
+
end
|
10
|
+
|
11
|
+
# xs:string format
|
12
|
+
def to_xml
|
13
|
+
value&.to_s
|
14
|
+
end
|
15
|
+
|
16
|
+
# JSON string
|
17
|
+
def to_json(*_args)
|
18
|
+
value
|
19
|
+
end
|
20
|
+
|
21
|
+
# YAML string
|
22
|
+
def to_yaml
|
23
|
+
value
|
24
|
+
end
|
25
|
+
|
26
|
+
# TOML string
|
27
|
+
def to_toml
|
28
|
+
value&.to_s
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.from_xml(value)
|
32
|
+
cast(value)
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.from_json(value)
|
36
|
+
cast(value)
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.from_yaml(value)
|
40
|
+
cast(value)
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.from_toml(value)
|
44
|
+
cast(value)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require "time"
|
2
|
+
|
3
|
+
module Lutaml
|
4
|
+
module Model
|
5
|
+
module Type
|
6
|
+
class Time < Value
|
7
|
+
def self.cast(value)
|
8
|
+
return nil if value.nil?
|
9
|
+
|
10
|
+
case value
|
11
|
+
when ::Time then value
|
12
|
+
when ::DateTime then value.to_time
|
13
|
+
else ::Time.parse(value.to_s)
|
14
|
+
end
|
15
|
+
rescue ArgumentError
|
16
|
+
nil
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.serialize(value)
|
20
|
+
return nil if value.nil?
|
21
|
+
|
22
|
+
value = cast(value)
|
23
|
+
# value&.strftime("%Y-%m-%dT%H:%M:%S%:z")
|
24
|
+
value&.iso8601
|
25
|
+
end
|
26
|
+
|
27
|
+
# # xs:time format (HH:MM:SS.mmm±HH:MM)
|
28
|
+
# def to_xml
|
29
|
+
# value&.strftime("%H:%M:%S%:z")
|
30
|
+
# end
|
31
|
+
|
32
|
+
# # ISO8601 time format
|
33
|
+
# def to_json
|
34
|
+
# value&.iso8601
|
35
|
+
# end
|
36
|
+
|
37
|
+
# # YAML timestamp format (native)
|
38
|
+
# def to_yaml
|
39
|
+
# value
|
40
|
+
# end
|
41
|
+
|
42
|
+
# # TOML time format (HH:MM:SS.mmm)
|
43
|
+
# def to_toml
|
44
|
+
# value&.strftime("%H:%M:%S.%L")
|
45
|
+
# end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -1,16 +1,48 @@
|
|
1
|
+
require "time"
|
2
|
+
|
1
3
|
module Lutaml
|
2
4
|
module Model
|
3
5
|
module Type
|
4
|
-
|
5
|
-
|
6
|
+
class TimeWithoutDate < Value
|
7
|
+
# TODO: we probably want to do something like this because using
|
8
|
+
# Time.parse will set the date to today.
|
9
|
+
#
|
10
|
+
# time = ::Time.parse(value.to_s)
|
11
|
+
# ::Time.new(1, 1, 1, time.hour, time.min, time.sec)
|
12
|
+
|
6
13
|
def self.cast(value)
|
7
|
-
return if value.nil?
|
14
|
+
return nil if value.nil?
|
8
15
|
|
9
|
-
|
16
|
+
case value
|
17
|
+
when ::Time then value
|
18
|
+
else ::Time.parse(value.to_s)
|
19
|
+
end
|
20
|
+
rescue ArgumentError
|
21
|
+
nil
|
10
22
|
end
|
11
23
|
|
12
24
|
def self.serialize(value)
|
13
|
-
value.
|
25
|
+
return nil if value.nil?
|
26
|
+
|
27
|
+
value = cast(value)
|
28
|
+
value.strftime("%H:%M:%S") # Format as HH:MM:SS
|
29
|
+
end
|
30
|
+
|
31
|
+
# Instance methods for format-specific serialization
|
32
|
+
def to_xml
|
33
|
+
self.class.serialize(value)
|
34
|
+
end
|
35
|
+
|
36
|
+
def to_json(*_args)
|
37
|
+
self.class.serialize(value)
|
38
|
+
end
|
39
|
+
|
40
|
+
def to_yaml
|
41
|
+
self.class.serialize(value)
|
42
|
+
end
|
43
|
+
|
44
|
+
def to_toml
|
45
|
+
value.strftime("%H:%M:%S.%L") # Include milliseconds for TOML
|
14
46
|
end
|
15
47
|
end
|
16
48
|
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require_relative "../config"
|
2
|
+
|
3
|
+
module Lutaml
|
4
|
+
module Model
|
5
|
+
module Type
|
6
|
+
# Base class for all value types
|
7
|
+
class Value
|
8
|
+
attr_reader :value
|
9
|
+
|
10
|
+
def initialize(value)
|
11
|
+
@value = self.class.cast(value)
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.cast(value)
|
15
|
+
return nil if value.nil?
|
16
|
+
|
17
|
+
value
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.serialize(value)
|
21
|
+
return nil if value.nil?
|
22
|
+
|
23
|
+
new(value).to_s
|
24
|
+
end
|
25
|
+
|
26
|
+
# Instance methods for serialization
|
27
|
+
def to_s
|
28
|
+
value.to_s
|
29
|
+
end
|
30
|
+
|
31
|
+
# Format-specific instance methods
|
32
|
+
::Lutaml::Model::Config::AVAILABLE_FORMATS.each do |format|
|
33
|
+
define_method(:"to_#{format}") do
|
34
|
+
value
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# Class-level format conversion
|
39
|
+
def self.from_format(value, format)
|
40
|
+
new(send(:"from_#{format}", value))
|
41
|
+
end
|
42
|
+
|
43
|
+
# Default format-specific class methods that can be overridden
|
44
|
+
::Lutaml::Model::Config::AVAILABLE_FORMATS.each do |format|
|
45
|
+
define_singleton_method(:"from_#{format}") do |value|
|
46
|
+
cast(value)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
data/lib/lutaml/model/type.rb
CHANGED
@@ -1,136 +1,72 @@
|
|
1
|
-
require "date"
|
2
|
-
require "bigdecimal"
|
3
|
-
|
4
1
|
module Lutaml
|
5
2
|
module Model
|
6
3
|
module Type
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
return if value.nil? # return if value.nil?
|
25
|
-
#
|
26
|
-
Type.cast(value, #{t}) # Type.cast(value, Integer)
|
27
|
-
end # end
|
28
|
-
|
29
|
-
def self.serialize(value) # def self.serialize(value)
|
30
|
-
return if value.nil? # return if value.nil?
|
31
|
-
#
|
32
|
-
Type.serialize(value, #{t}) # Type.serialize(value, Integer)
|
33
|
-
end # end
|
34
|
-
end # end
|
35
|
-
HEREDOC
|
36
|
-
end
|
37
|
-
|
38
|
-
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/
|
39
|
-
|
40
|
-
def self.cast(value, type)
|
41
|
-
return if value.nil?
|
42
|
-
|
43
|
-
case type.to_s.split("::").last
|
44
|
-
when "String"
|
45
|
-
value.to_s
|
46
|
-
when "Integer"
|
47
|
-
value.to_i
|
48
|
-
when "Float"
|
49
|
-
value.to_f
|
50
|
-
when "Date"
|
51
|
-
begin
|
52
|
-
::Date.parse(value.to_s)
|
53
|
-
rescue ArgumentError
|
54
|
-
nil
|
55
|
-
end
|
56
|
-
when "DateTime"
|
57
|
-
DateTime.cast(value)
|
58
|
-
when "Time"
|
59
|
-
::Time.parse(value.to_s)
|
60
|
-
when "TimeWithoutDate"
|
61
|
-
TimeWithoutDate.cast(value)
|
62
|
-
when "Boolean"
|
63
|
-
to_boolean(value)
|
64
|
-
when "Decimal"
|
65
|
-
unless defined?(BigDecimal)
|
66
|
-
raise Lutaml::Model::TypeNotEnabledError.new("Decimal", value)
|
4
|
+
TYPE_CODES = {
|
5
|
+
string: "Lutaml::Model::Type::String",
|
6
|
+
integer: "Lutaml::Model::Type::Integer",
|
7
|
+
float: "Lutaml::Model::Type::Float",
|
8
|
+
decimal: "Lutaml::Model::Type::Decimal",
|
9
|
+
date: "Lutaml::Model::Type::Date",
|
10
|
+
time: "Lutaml::Model::Type::Time",
|
11
|
+
date_time: "Lutaml::Model::Type::DateTime",
|
12
|
+
time_without_date: "Lutaml::Model::Type::TimeWithoutDate",
|
13
|
+
boolean: "Lutaml::Model::Type::Boolean",
|
14
|
+
hash: "Lutaml::Model::Type::Hash",
|
15
|
+
}.freeze
|
16
|
+
|
17
|
+
class << self
|
18
|
+
def register_builtin_types
|
19
|
+
TYPE_CODES.each do |type_name, type_class|
|
20
|
+
register(type_name, const_get(type_class))
|
67
21
|
end
|
68
|
-
|
69
|
-
BigDecimal(value.to_s)
|
70
|
-
when "Hash"
|
71
|
-
normalize_hash(Hash(value))
|
72
|
-
else
|
73
|
-
value
|
74
22
|
end
|
75
|
-
end
|
76
|
-
|
77
|
-
def self.serialize(value, type)
|
78
|
-
return if value.nil?
|
79
23
|
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
DateTime.serialize(value)
|
85
|
-
when "Integer"
|
86
|
-
value.to_i
|
87
|
-
when "Float"
|
88
|
-
value.to_f
|
89
|
-
when "Boolean"
|
90
|
-
to_boolean(value)
|
91
|
-
when "Decimal"
|
92
|
-
unless defined?(BigDecimal)
|
93
|
-
raise Lutaml::Model::TypeNotEnabledError.new("Decimal", value)
|
24
|
+
def register(type_name, type_class)
|
25
|
+
unless type_class < Value
|
26
|
+
raise TypeError,
|
27
|
+
"class '#{type_class}' is not a valid Lutaml::Model::Type::Value"
|
94
28
|
end
|
95
29
|
|
96
|
-
|
97
|
-
|
98
|
-
Hash(value)
|
99
|
-
else
|
100
|
-
value.to_s
|
30
|
+
@registry ||= {}
|
31
|
+
@registry[type_name.to_sym] = type_class
|
101
32
|
end
|
102
|
-
end
|
103
33
|
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
end
|
34
|
+
def lookup(type_name)
|
35
|
+
@registry ||= {}
|
36
|
+
klass = @registry[type_name.to_sym]
|
108
37
|
|
109
|
-
|
110
|
-
return false
|
111
|
-
end
|
38
|
+
raise UnknownTypeError.new(type_name) unless klass
|
112
39
|
|
113
|
-
|
114
|
-
|
40
|
+
klass
|
41
|
+
end
|
115
42
|
|
116
|
-
|
117
|
-
|
43
|
+
def cast(value, type)
|
44
|
+
return nil if value.nil?
|
118
45
|
|
119
|
-
|
46
|
+
type.cast(value)
|
47
|
+
end
|
120
48
|
|
121
|
-
|
122
|
-
|
49
|
+
def serialize(value, type)
|
50
|
+
return nil if value.nil?
|
123
51
|
|
124
|
-
|
125
|
-
|
126
|
-
else
|
127
|
-
[key, value]
|
128
|
-
end
|
129
|
-
end.to_h
|
52
|
+
type.serialize(value)
|
53
|
+
end
|
130
54
|
end
|
131
55
|
end
|
132
56
|
end
|
133
57
|
end
|
134
58
|
|
135
|
-
|
59
|
+
# Register built-in types
|
60
|
+
require_relative "type/value"
|
61
|
+
require_relative "type/string"
|
62
|
+
require_relative "type/integer"
|
63
|
+
require_relative "type/float"
|
64
|
+
require_relative "type/date"
|
65
|
+
require_relative "type/time"
|
136
66
|
require_relative "type/date_time"
|
67
|
+
require_relative "type/time_without_date"
|
68
|
+
require_relative "type/boolean"
|
69
|
+
require_relative "type/decimal"
|
70
|
+
require_relative "type/hash"
|
71
|
+
|
72
|
+
Lutaml::Model::Type.register_builtin_types
|
data/lib/lutaml/model/version.rb
CHANGED
@@ -39,6 +39,8 @@ module Lutaml
|
|
39
39
|
)
|
40
40
|
add_namespace_prefix(prefix)
|
41
41
|
|
42
|
+
element_name = "#{element_name}_" if respond_to?(element_name)
|
43
|
+
|
42
44
|
if block_given?
|
43
45
|
public_send(element_name, attributes) do
|
44
46
|
xml.parent.namespace = nil if prefix.nil? && !prefix_unset
|
@@ -54,7 +56,8 @@ module Lutaml
|
|
54
56
|
element = element.xml.parent
|
55
57
|
end
|
56
58
|
|
57
|
-
|
59
|
+
text_node = ::Nokogiri::XML::Text.new(text.to_s, element)
|
60
|
+
element.add_child(text_node)
|
58
61
|
end
|
59
62
|
|
60
63
|
def add_namespace_prefix(prefix)
|
@@ -64,7 +67,7 @@ module Lutaml
|
|
64
67
|
end
|
65
68
|
|
66
69
|
def method_missing(method_name, *args, &block)
|
67
|
-
if
|
70
|
+
if block_given?
|
68
71
|
xml.public_send(method_name, *args, &block)
|
69
72
|
else
|
70
73
|
xml.public_send(method_name, *args)
|