lutaml-model 0.3.10 → 0.3.11

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5140f93f22f4b05222edc408aeca50552082e447b71fddd724b34ba9e6b82d55
4
- data.tar.gz: 0aa44a3c72b65cca0ed2b7411614d8cdb0c44b4e8293e183935cb45ba7818d7c
3
+ metadata.gz: 91ff48fd66cf1435e5e18508b24cc24f7cc92dc8b5d1619c7796932eb21dcea2
4
+ data.tar.gz: 51eabdb2aede716ce86cea46325cad0b7b9f0da98df3235fc3b8596fe9f96bd9
5
5
  SHA512:
6
- metadata.gz: 69e4d0d0a3a5bd19e11a43fd33e03566ca035d18cf948a0a2fc5abe5f880489e4a6ad347d8118a04c35c8c95be5b7eb29ca93d426643c7790ab045db2b34721c
7
- data.tar.gz: df1699ba6647f53f97735d0986b92bf8f76d6bf44430117406100b257f5934ac4a7baa6a4243bb8384db277ecb975bf64efe2f1a16b293739b245150e800cb15
6
+ metadata.gz: 3ce25727c43d1c25f97e49c529c9ded5f51d8f2c13ae2766dba8c94d2c1d9a7c646bad564bfb9cd4c5555ee71395f6ff39023268e9e92044f10985c20dd826ca
7
+ data.tar.gz: edf1d699e944a2427b947e1a262258e93623c44bc765a5f5497c13bd4d806984722ececd6318254c15196d435b2b809f44389a1be1d9cd5f33e005169b232eaf
data/.rubocop_todo.yml CHANGED
@@ -1,25 +1,18 @@
1
1
  # This configuration was generated by
2
2
  # `rubocop --auto-gen-config`
3
- # on 2024-09-10 23:53:08 UTC using RuboCop version 1.66.1.
3
+ # on 2024-09-23 15:00:23 UTC using RuboCop version 1.65.1.
4
4
  # The point is for the user to remove these configuration records
5
5
  # one by one as the offenses are removed from the code base.
6
6
  # Note that changes in the inspected code, or installation of new
7
7
  # versions of RuboCop, may require this file to be generated again.
8
8
 
9
- # Offense count: 88
9
+ # Offense count: 100
10
10
  # This cop supports safe autocorrection (--autocorrect).
11
11
  # Configuration parameters: Max, AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, AllowedPatterns.
12
12
  # URISchemes: http, https
13
13
  Layout/LineLength:
14
14
  Enabled: false
15
15
 
16
- # Offense count: 1
17
- # This cop supports safe autocorrection (--autocorrect).
18
- # Configuration parameters: AllowInHeredoc.
19
- Layout/TrailingWhitespace:
20
- Exclude:
21
- - 'lib/lutaml/model/schema_location.rb'
22
-
23
16
  # Offense count: 11
24
17
  # Configuration parameters: AllowedMethods.
25
18
  # AllowedMethods: enums
@@ -37,12 +30,13 @@ Lint/DuplicateMethods:
37
30
  Exclude:
38
31
  - 'lib/lutaml/model/attribute.rb'
39
32
 
40
- # Offense count: 31
33
+ # Offense count: 34
41
34
  # Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes, Max.
42
35
  Metrics/AbcSize:
43
36
  Exclude:
44
37
  - 'lib/lutaml/model/attribute.rb'
45
38
  - 'lib/lutaml/model/comparable_model.rb'
39
+ - 'lib/lutaml/model/mapping_rule.rb'
46
40
  - 'lib/lutaml/model/schema/relaxng_schema.rb'
47
41
  - 'lib/lutaml/model/schema/xsd_schema.rb'
48
42
  - 'lib/lutaml/model/serialize.rb'
@@ -51,13 +45,13 @@ Metrics/AbcSize:
51
45
  - 'lib/lutaml/model/xml_adapter/ox_adapter.rb'
52
46
  - 'lib/lutaml/model/xml_adapter/xml_document.rb'
53
47
 
54
- # Offense count: 6
48
+ # Offense count: 4
55
49
  # Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns, inherit_mode.
56
50
  # AllowedMethods: refine
57
51
  Metrics/BlockLength:
58
52
  Max: 42
59
53
 
60
- # Offense count: 25
54
+ # Offense count: 26
61
55
  # Configuration parameters: AllowedMethods, AllowedPatterns, Max.
62
56
  Metrics/CyclomaticComplexity:
63
57
  Exclude:
@@ -69,17 +63,17 @@ Metrics/CyclomaticComplexity:
69
63
  - 'lib/lutaml/model/xml_adapter/ox_adapter.rb'
70
64
  - 'lib/lutaml/model/xml_adapter/xml_document.rb'
71
65
 
72
- # Offense count: 39
66
+ # Offense count: 45
73
67
  # Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns.
74
68
  Metrics/MethodLength:
75
- Max: 49
69
+ Max: 51
76
70
 
77
71
  # Offense count: 4
78
72
  # Configuration parameters: CountKeywordArgs, MaxOptionalParameters.
79
73
  Metrics/ParameterLists:
80
- Max: 9
74
+ Max: 10
81
75
 
82
- # Offense count: 21
76
+ # Offense count: 22
83
77
  # Configuration parameters: AllowedMethods, AllowedPatterns, Max.
84
78
  Metrics/PerceivedComplexity:
85
79
  Exclude:
@@ -100,10 +94,10 @@ RSpec/ContextWording:
100
94
  - 'spec/lutaml/model/xml_adapter/ox_adapter_spec.rb'
101
95
  - 'spec/lutaml/model/xml_adapter/xml_namespace_spec.rb'
102
96
 
103
- # Offense count: 101
97
+ # Offense count: 105
104
98
  # Configuration parameters: CountAsOne.
105
99
  RSpec/ExampleLength:
106
- Max: 57
100
+ Max: 54
107
101
 
108
102
  # Offense count: 2
109
103
  # Configuration parameters: Max, AllowedIdentifiers, AllowedPatterns.
@@ -129,11 +123,11 @@ RSpec/MultipleDescribes:
129
123
  - 'spec/lutaml/model/xml_adapter/xml_namespace_spec.rb'
130
124
  - 'spec/lutaml/model/xml_adapter_spec.rb'
131
125
 
132
- # Offense count: 88
126
+ # Offense count: 98
133
127
  RSpec/MultipleExpectations:
134
- Max: 11
128
+ Max: 14
135
129
 
136
- # Offense count: 17
130
+ # Offense count: 18
137
131
  # Configuration parameters: AllowSubject.
138
132
  RSpec/MultipleMemoizedHelpers:
139
133
  Max: 9
@@ -147,18 +141,24 @@ RSpec/PendingWithoutReason:
147
141
  - 'spec/lutaml/model/xml_adapter/xml_namespace_spec.rb'
148
142
  - 'spec/lutaml/model/xml_adapter_spec.rb'
149
143
 
144
+ # Offense count: 1
145
+ RSpec/RemoveConst:
146
+ Exclude:
147
+ - 'spec/lutaml/model/type/decimal_spec.rb'
148
+
150
149
  # Offense count: 2
151
150
  RSpec/RepeatedExampleGroupDescription:
152
151
  Exclude:
153
152
  - 'spec/lutaml/model/collection_spec.rb'
154
153
 
155
- # Offense count: 1
154
+ # Offense count: 2
156
155
  # Configuration parameters: Include, CustomTransform, IgnoreMethods, IgnoreMetadata.
157
156
  # Include: **/*_spec.rb
158
157
  RSpec/SpecFilePathFormat:
159
158
  Exclude:
160
159
  - '**/spec/routing/**/*'
161
160
  - 'spec/lutaml/model/collection_spec.rb'
161
+ - 'spec/lutaml/model/type/decimal_spec.rb'
162
162
 
163
163
  # Offense count: 1
164
164
  Security/CompoundHash:
data/Gemfile CHANGED
@@ -5,6 +5,7 @@ source "https://rubygems.org"
5
5
  # Specify your gem's dependencies in lutaml-model.gemspec
6
6
  gemspec
7
7
 
8
+ gem "bigdecimal"
8
9
  gem "equivalent-xml"
9
10
  gem "multi_json"
10
11
  gem "nokogiri"
data/LICENSE.md ADDED
@@ -0,0 +1,33 @@
1
+ Licenses & Copyright
2
+ ====================
3
+
4
+ This license file adheres to the formatting guidelines of
5
+ [readable-licenses](https://github.com/nevir/readable-licenses).
6
+
7
+
8
+ Ribose's BSD 2-Clause License
9
+ -----------------------------
10
+
11
+ Copyright (c) 2024, [Ribose Inc](https://www.ribose.com).
12
+ All rights reserved.
13
+
14
+ Redistribution and use in source and binary forms, with or without modification,
15
+ are permitted provided that the following conditions are met:
16
+
17
+ 1. Redistributions of source code must retain the above copyright notice,
18
+ this list of conditions and the following disclaimer.
19
+
20
+ 2. Redistributions in binary form must reproduce the above copyright notice,
21
+ this list of conditions and the following disclaimer in the documentation
22
+ and/or other materials provided with the distribution.
23
+
24
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
25
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
26
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
28
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
30
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
31
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
32
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
33
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
data/README.adoc CHANGED
@@ -145,6 +145,8 @@ same class and all their attributes are equal.
145
145
 
146
146
  === Supported attribute value types
147
147
 
148
+ ==== General types
149
+
148
150
  Lutaml::Model supports the following attribute types, they can be
149
151
  referred by a string, a symbol, or their class constant.
150
152
 
@@ -166,12 +168,11 @@ attribute :name_of_attribute, {symbol | string | class}
166
168
  | `DateTime` | `:date_time` | `Lutaml::Model::Type::DateTime` | `::DateTime`
167
169
  | `TimeWithoutDate` | `:time_without_date` | `Lutaml::Model::Type::TimeWithoutDate` | `::Time`
168
170
  | `Boolean` | `:boolean` | `Lutaml::Model::Type::Boolean` | `Boolean`
169
- | `Decimal` | `:decimal` | `Lutaml::Model::Type::Decimal` | `::BigDecimal`
171
+ | `Decimal` (optional) | `:decimal` | `Lutaml::Model::Type::Decimal` | `::BigDecimal`
170
172
  | `Hash` | `:hash` | `Lutaml::Model::Type::Hash` | `::Hash`
171
173
 
172
174
  |===
173
175
 
174
-
175
176
  .Defining attributes with supported types via symbol, string and class
176
177
  [example]
177
178
  ====
@@ -198,6 +199,23 @@ end
198
199
  ----
199
200
  ====
200
201
 
202
+ ==== (optional) Decimal type
203
+
204
+ The `BigDecimal` class is no longer part of the standard Ruby library from Ruby
205
+ 3.4 onwards, hence the `Decimal` type is only enabled when the `bigdecimal`
206
+ library is loaded.
207
+
208
+ This means that the following code needs to be run before using (and parsing)
209
+ the `Decimal` type:
210
+
211
+ [source,ruby]
212
+ ----
213
+ require 'bigdecimal'
214
+ ----
215
+
216
+ If the `bigdecimal` library is not loaded, usage of the `Decimal` type will
217
+ raise a `Lutaml::Model::TypeNotSupportedError`.
218
+
201
219
 
202
220
  === Attribute as a collection
203
221
 
@@ -989,7 +1007,7 @@ end
989
1007
 
990
1008
  TODO: How to create mixed content from `#new`?
991
1009
 
992
-
1010
+ [[xml-schema-location]]
993
1011
  ==== Automatic support of `xsi:schemaLocation`
994
1012
 
995
1013
  The
@@ -1444,9 +1462,14 @@ NOTE: The corresponding keyword used by Shale is `receiver:` instead of
1444
1462
 
1445
1463
  ==== Attribute serialization with custom methods
1446
1464
 
1465
+ ===== General
1466
+
1447
1467
  Define custom methods for specific attribute mappings using the `with:` key for
1448
1468
  each serialization mapping block for `from` and `to`.
1449
1469
 
1470
+
1471
+ ===== XML serialization with custom methods
1472
+
1450
1473
  Syntax:
1451
1474
 
1452
1475
  .XML serialization with custom methods
@@ -1468,6 +1491,81 @@ xml do
1468
1491
  end
1469
1492
  ----
1470
1493
 
1494
+ .Using the `with:` key to define custom serialization methods for XML
1495
+ [example]
1496
+ ====
1497
+ The following class will parse the XML snippet below:
1498
+
1499
+ [source,ruby]
1500
+ ----
1501
+ class CustomCeramic < Lutaml::Model::Serializable
1502
+ attribute :name, :string
1503
+ attribute :size, :integer
1504
+ attribute :description, :string
1505
+
1506
+ xml do
1507
+ map_element "Name", to: :name, with: { to: :name_to_xml, from: :name_from_xml }
1508
+ map_attribute "Size", to: :size, with: { to: :size_to_xml, from: :size_from_xml }
1509
+ map_content with: { to: :description_to_xml, from: :description_from_xml }
1510
+ end
1511
+
1512
+ def name_to_xml(model, parent, doc)
1513
+ el = doc.create_element("Name")
1514
+ doc.add_text(el, "XML Masterpiece: #{model.name}")
1515
+ doc.add_element(parent, el)
1516
+ end
1517
+
1518
+ def name_from_xml(model, value)
1519
+ model.name = value.sub(/^XML Masterpiece: /, "")
1520
+ end
1521
+
1522
+ def size_to_xml(model, parent, doc)
1523
+ doc.add_attribute(parent, "Size", model.size + 3)
1524
+ end
1525
+
1526
+ def size_from_xml(model, value)
1527
+ model.size = value.to_i - 3
1528
+ end
1529
+
1530
+ def description_to_xml(model, parent, doc)
1531
+ doc.add_text(parent, "XML Description: #{model.description}")
1532
+ end
1533
+
1534
+ def description_from_xml(model, value)
1535
+ model.description = value.join.strip.sub(/^XML Description: /, "")
1536
+ end
1537
+ end
1538
+ ----
1539
+
1540
+ [source,xml]
1541
+ ----
1542
+ <CustomCeramic Size="15">
1543
+ <Name>XML Masterpiece: Vase</Name>
1544
+ XML Description: A beautiful ceramic vase
1545
+ </CustomCeramic>
1546
+ ----
1547
+
1548
+ [source,ruby]
1549
+ ----
1550
+ > CustomCeramic.from_xml(xml)
1551
+ > #<CustomCeramic:0x0000000108d0e1f8
1552
+ @element_order=["text", "Name", "text", "Size", "text"],
1553
+ @name="Masterpiece: Vase",
1554
+ @ordered=nil,
1555
+ @size=12,
1556
+ @description="A beautiful ceramic vase",
1557
+ @validate_on_set=false>
1558
+ > puts CustomCeramic.new(name: "Vase", size: 12, description: "A beautiful vase").to_xml
1559
+ # <CustomCeramic Size="15">
1560
+ # <Name>XML Masterpiece: Vase</Name>
1561
+ # XML Description: A beautiful vase
1562
+ # </CustomCeramic>
1563
+ ----
1564
+ ====
1565
+
1566
+
1567
+ ===== Key-value data model serialization with custom methods
1568
+
1471
1569
  .Key-value data model serialization with custom methods
1472
1570
  [source,ruby]
1473
1571
  ----
@@ -1524,7 +1622,7 @@ end
1524
1622
 
1525
1623
 
1526
1624
  [[attribute-extraction]]
1527
- ==== Attribute extraction
1625
+ ==== Attribute extraction (for key-value data models only)
1528
1626
 
1529
1627
  NOTE: This feature is for key-value data model serialization only.
1530
1628
 
@@ -1992,9 +2090,9 @@ differences in implementation.
1992
2090
  |
1993
2091
 
1994
2092
  | Value types
1995
- | `Lutaml::Model::Type` includes: `Integer`, `String`, `Float`, `Boolean`, `Date`, `DateTime`, `Time`, `Hash`.
2093
+ | `Lutaml::Model::Type` includes: `Integer`, `String`, `Float`, `Boolean`, `Date`, `DateTime`, `Time`, `Decimal`, `Hash`.
1996
2094
  | `Shale::Type` includes: `Integer`, `String`, `Float`, `Boolean`, `Date`, `Time`.
1997
- | Lutaml::Model supports the additional value types `DateTime` and `Hash`.
2095
+ | Lutaml::Model supports additional value types `Decimal`, `DateTime` and `Hash`.
1998
2096
 
1999
2097
  | Configuration
2000
2098
  | `Lutaml::Model::Config`
@@ -2011,6 +2109,11 @@ differences in implementation.
2011
2109
  | XML, YAML, JSON, TOML, CSV
2012
2110
  | Lutaml::Model does not support CSV.
2013
2111
 
2112
+ | Validation
2113
+ | Supports collection range, fixed values, and custom validation
2114
+ | Requires implementation
2115
+ |
2116
+
2014
2117
  | Adapter support
2015
2118
  | XML (Nokogiri, Ox, Oga), YAML, JSON (JSON, MultiJson), TOML (Toml-rb, Tomlib)
2016
2119
  | XML (Nokogiri, Ox), YAML, JSON (JSON, MultiJson), TOML (Toml-rb, Tomlib), CSV
@@ -2042,6 +2145,12 @@ namespace from the root element.
2042
2145
  | No.
2043
2146
  |
2044
2147
 
2148
+ | Support for `xsi:schemaLocation`
2149
+ | Yes. Automatically supports the <<xml-schema-location,`xsi:schemaLocation`>>
2150
+ attribute for every element.
2151
+ | Requires manual specification on every XML element that uses it.
2152
+ |
2153
+
2045
2154
  4+h| Attribute features
2046
2155
 
2047
2156
  | Attribute delegation
@@ -2061,7 +2170,6 @@ data models.
2061
2170
  | No.
2062
2171
  | Lutaml::Model supports attribute extraction from key-value data models.
2063
2172
 
2064
-
2065
2173
  |===
2066
2174
 
2067
2175
 
@@ -2114,25 +2222,26 @@ Actions:
2114
2222
 
2115
2223
  === Step 2: Replace value type definitions
2116
2224
 
2117
- Value types in `Lutaml::Model` are under the `Lutaml::Model::Type` module.
2225
+ Value types in `Lutaml::Model` are under the `Lutaml::Model::Type` module,
2226
+ or use the LutaML type symbols.
2118
2227
 
2119
2228
  [source,ruby]
2120
2229
  ----
2121
2230
  class Example < Lutaml::Model::Serializable
2122
- attribute :length, Lutaml::Model::Type::Integer
2123
- attribute :description, Lutaml::Model::Type::String
2231
+ attribute :length, :integer
2232
+ attribute :description, :string
2124
2233
  end
2125
2234
  ----
2126
2235
 
2127
2236
  [NOTE]
2128
2237
  ====
2129
- `Lutaml::Model` also supports specifying predefined value types as strings or
2238
+ `Lutaml::Model` supports specifying predefined value types as strings or
2130
2239
  symbols, which is not supported by Shale.
2131
2240
 
2132
2241
  [source,ruby]
2133
2242
  ----
2134
2243
  class Example < Lutaml::Model::Serializable
2135
- attribute :length, :integer
2244
+ attribute :length, Lutaml::Model::Type::Integer
2136
2245
  attribute :description, "String"
2137
2246
  end
2138
2247
  ----
@@ -2369,6 +2478,6 @@ allowing you to shape and structure your data into useful forms.
2369
2478
  == License and Copyright
2370
2479
 
2371
2480
  This project is licensed under the BSD 2-clause License.
2372
- See the LICENSE file for details.
2481
+ See the link:LICENSE.md[] file for details.
2373
2482
 
2374
2483
  Copyright Ribose.
@@ -27,6 +27,16 @@ module Lutaml
27
27
  raise ArgumentError, "Unknown Lutaml::Model::Type: #{type}"
28
28
  end
29
29
 
30
+ def cast_value(value)
31
+ return type.cast(value) unless value.is_a?(Array)
32
+
33
+ value.map { |v| type.cast(v) }
34
+ end
35
+
36
+ def setter
37
+ :"#{@name}="
38
+ end
39
+
30
40
  def collection?
31
41
  options[:collection] || false
32
42
  end
@@ -36,9 +46,13 @@ module Lutaml
36
46
  end
37
47
 
38
48
  def default
39
- return options[:default].call if options[:default].is_a?(Proc)
49
+ value = if options[:default].is_a?(Proc)
50
+ options[:default].call
51
+ else
52
+ options[:default]
53
+ end
40
54
 
41
- options[:default]
55
+ cast_value(value)
42
56
  end
43
57
 
44
58
  def render_nil?
@@ -0,0 +1,6 @@
1
+ module Lutaml
2
+ module Model
3
+ class IncorrectMappingArgumentsError < Error
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,9 @@
1
+ module Lutaml
2
+ module Model
3
+ class TypeNotEnabledError < Error
4
+ def initialize(type_name, value)
5
+ super("#{type_name} type is not enabled. Value: #{value}")
6
+ end
7
+ end
8
+ end
9
+ end
@@ -6,6 +6,8 @@ module Lutaml
6
6
  end
7
7
 
8
8
  require_relative "error/invalid_value_error"
9
+ require_relative "error/incorrect_mapping_argument_error"
9
10
  require_relative "error/unknown_adapter_type_error"
10
11
  require_relative "error/collection_count_out_of_range_error"
11
12
  require_relative "error/validation_error"
13
+ require_relative "error/type_not_enabled_error"
@@ -6,8 +6,7 @@ module Lutaml
6
6
  module JsonAdapter
7
7
  class StandardJsonAdapter < JsonDocument
8
8
  def self.parse(json)
9
- attributes = JSON.parse(json, create_additions: false)
10
- new(attributes)
9
+ JSON.parse(json, create_additions: false)
11
10
  end
12
11
 
13
12
  def to_json(*args)
@@ -11,12 +11,14 @@ module Lutaml
11
11
 
12
12
  def map(
13
13
  name,
14
- to:,
14
+ to: nil,
15
15
  render_nil: false,
16
16
  with: {},
17
17
  delegate: nil,
18
18
  child_mappings: nil
19
19
  )
20
+ validate!(name, to, with)
21
+
20
22
  @mappings << KeyValueMappingRule.new(
21
23
  name,
22
24
  to: to,
@@ -28,6 +30,18 @@ module Lutaml
28
30
  end
29
31
 
30
32
  alias map_element map
33
+
34
+ def validate!(key, to, with)
35
+ if to.nil? && with.empty?
36
+ msg = ":to or :with argument is required for mapping '#{key}'"
37
+ raise IncorrectMappingArgumentsError.new(msg)
38
+ end
39
+
40
+ if !with.empty? && (with[:from].nil? || with[:to].nil?)
41
+ msg = ":with argument for mapping '#{key}' requires :to and :from keys"
42
+ raise IncorrectMappingArgumentsError.new(msg)
43
+ end
44
+ end
31
45
  end
32
46
  end
33
47
  end
@@ -24,6 +24,20 @@ module Lutaml
24
24
  @ordered
25
25
  end
26
26
 
27
+ def method_missing(method_name, *args)
28
+ value = self[method_name] || self[method_name.to_s]
29
+ return value if value
30
+
31
+ super
32
+ end
33
+
34
+ def respond_to_missing?(method_name, include_private = false)
35
+ key_present = key?(method_name) || key?(method_name.to_s)
36
+ return true if key_present
37
+
38
+ super
39
+ end
40
+
27
41
  private
28
42
 
29
43
  def normalize(key)
@@ -17,6 +17,7 @@ module Lutaml
17
17
  delegate: nil,
18
18
  mixed_content: false,
19
19
  namespace_set: false,
20
+ prefix_set: false,
20
21
  child_mappings: nil
21
22
  )
22
23
  @name = name
@@ -26,6 +27,7 @@ module Lutaml
26
27
  @delegate = delegate
27
28
  @mixed_content = mixed_content
28
29
  @namespace_set = namespace_set
30
+ @prefix_set = prefix_set
29
31
  @child_mappings = child_mappings
30
32
  end
31
33
 
@@ -40,25 +42,47 @@ module Lutaml
40
42
  end
41
43
  end
42
44
 
43
- def serialize(model, value)
45
+ def serialize_attribute(model, element, doc)
44
46
  if custom_methods[:to]
45
- model.send(custom_methods[:to], model, value)
47
+ model.send(custom_methods[:to], model, element, doc)
48
+ end
49
+ end
50
+
51
+ def serialize(model, parent = nil, doc = nil)
52
+ if custom_methods[:to]
53
+ model.send(custom_methods[:to], model, parent, doc)
54
+ elsif delegate
55
+ model.public_send(delegate).public_send(to)
46
56
  else
47
- value
57
+ model.public_send(to)
48
58
  end
49
59
  end
50
60
 
51
- def deserialize(model, doc)
61
+ def deserialize(model, value, attributes, mapper_class = nil)
52
62
  if custom_methods[:from]
53
- model.send(custom_methods[:from], model, doc)
63
+ mapper_class.new.send(custom_methods[:from], model, value)
64
+ elsif delegate
65
+ if model.public_send(delegate).nil?
66
+ model.public_send(:"#{delegate}=", attributes[delegate].type.new)
67
+ end
68
+
69
+ model.public_send(delegate).public_send(:"#{to}=", value)
54
70
  else
55
- doc[name.to_s]
71
+ model.public_send(:"#{to}=", value)
56
72
  end
57
73
  end
58
74
 
59
75
  def namespace_set?
60
76
  @namespace_set
61
77
  end
78
+
79
+ def prefix_set?
80
+ @prefix_set
81
+ end
82
+
83
+ def content_mapping?
84
+ name.nil?
85
+ end
62
86
  end
63
87
  end
64
88
  end