lutaml-model 0.3.6 → 0.3.7

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: 45fc67305626a2fe4d38db31804a618fd887a9855ff8ddb7ef2d0d0e8cc8b9b8
4
- data.tar.gz: 7ffbc1f1b1958d05ebbf82889b1b54f032df48a4ed9052f3a963b896bfb43238
3
+ metadata.gz: 8362f4af3671083805d20014ef7e2422358aac08f1c15036a283dbedb91225ca
4
+ data.tar.gz: 661838fcd61e972cd1827a1b4889b3d2073e7a8db16a4fce371dcbf09fb79b96
5
5
  SHA512:
6
- metadata.gz: 37a4e64c1b61b6a1112329b18ea4bd9b544fe125859cd81a1054b162817e1ffb22e03f4168836ce8890e6f6cba6f137c78110522322c0a0fe6fde3e121c533d4
7
- data.tar.gz: bd3bfb6600103c25034c3604fcdc83947d8eb3a14b23ec54e93186f66d273a5270a923394bd5f00e5caf3d58c9ff7c65efce9cd5f7a874ac22f4582711622d27
6
+ metadata.gz: 31757feb85022ff8472b8e178ff433a84e2dcbd7a00b6cc2055f3f4d860b4470201c2ee6c39d2a2b96cc86d96ec3654affd7078bb2cad595345afa50fec9826d
7
+ data.tar.gz: ff6f2048f11d46a9e4df1ec872bca13e5ebcbbc098aa35689840e3601d18337e2e7a85afd48f8a67b1b39482782258cdc1494f13eb1cd67eac8ac37cc2f5809d
data/.rubocop_todo.yml CHANGED
@@ -1,6 +1,6 @@
1
1
  # This configuration was generated by
2
2
  # `rubocop --auto-gen-config`
3
- # on 2024-08-19 03:44:26 UTC using RuboCop version 1.65.1.
3
+ # on 2024-08-23 04:30:59 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
@@ -14,7 +14,76 @@ Gemspec/RequireMFA:
14
14
  Exclude:
15
15
  - 'lutaml-model.gemspec'
16
16
 
17
- # Offense count: 78
17
+ # Offense count: 28
18
+ # This cop supports safe autocorrection (--autocorrect).
19
+ # Configuration parameters: EnforcedStyle, IndentationWidth.
20
+ # SupportedStyles: with_first_argument, with_fixed_indentation
21
+ Layout/ArgumentAlignment:
22
+ Exclude:
23
+ - 'lib/lutaml/model/serialize.rb'
24
+ - 'lib/lutaml/model/xml_adapter/nokogiri_adapter.rb'
25
+ - 'lib/lutaml/model/xml_adapter/ox_adapter.rb'
26
+ - 'lib/lutaml/model/xml_adapter/xml_document.rb'
27
+ - 'spec/lutaml/model/serializable_spec.rb'
28
+
29
+ # Offense count: 1
30
+ # This cop supports safe autocorrection (--autocorrect).
31
+ # Configuration parameters: IndentationWidth.
32
+ Layout/AssignmentIndentation:
33
+ Exclude:
34
+ - 'lib/lutaml/model/xml_adapter/nokogiri_adapter.rb'
35
+
36
+ # Offense count: 6
37
+ # This cop supports safe autocorrection (--autocorrect).
38
+ # Configuration parameters: EnforcedStyleAlignWith.
39
+ # SupportedStylesAlignWith: either, start_of_block, start_of_line
40
+ Layout/BlockAlignment:
41
+ Exclude:
42
+ - 'lib/lutaml/model/xml_adapter/xml_document.rb'
43
+ - 'spec/lutaml/model/serializable_spec.rb'
44
+
45
+ # Offense count: 6
46
+ # This cop supports safe autocorrection (--autocorrect).
47
+ Layout/BlockEndNewline:
48
+ Exclude:
49
+ - 'lib/lutaml/model/xml_adapter/xml_document.rb'
50
+ - 'spec/lutaml/model/serializable_spec.rb'
51
+
52
+ # Offense count: 1
53
+ # This cop supports safe autocorrection (--autocorrect).
54
+ Layout/EmptyLineAfterGuardClause:
55
+ Exclude:
56
+ - 'lib/lutaml/model/serialize.rb'
57
+
58
+ # Offense count: 16
59
+ # This cop supports safe autocorrection (--autocorrect).
60
+ # Configuration parameters: AllowMultipleStyles, EnforcedHashRocketStyle, EnforcedColonStyle, EnforcedLastArgumentHashStyle.
61
+ # SupportedHashRocketStyles: key, separator, table
62
+ # SupportedColonStyles: key, separator, table
63
+ # SupportedLastArgumentHashStyles: always_inspect, always_ignore, ignore_implicit, ignore_explicit
64
+ Layout/HashAlignment:
65
+ Exclude:
66
+ - 'lib/lutaml/model/serialize.rb'
67
+ - 'lib/lutaml/model/xml_adapter/xml_document.rb'
68
+ - 'spec/lutaml/model/serializable_spec.rb'
69
+
70
+ # Offense count: 1
71
+ # This cop supports safe autocorrection (--autocorrect).
72
+ # Configuration parameters: EnforcedStyle.
73
+ # SupportedStyles: normal, indented_internal_methods
74
+ Layout/IndentationConsistency:
75
+ Exclude:
76
+ - 'lutaml-model.gemspec'
77
+
78
+ # Offense count: 12
79
+ # This cop supports safe autocorrection (--autocorrect).
80
+ # Configuration parameters: Width, AllowedPatterns.
81
+ Layout/IndentationWidth:
82
+ Exclude:
83
+ - 'lib/lutaml/model/xml_adapter/xml_document.rb'
84
+ - 'spec/lutaml/model/serializable_spec.rb'
85
+
86
+ # Offense count: 83
18
87
  # This cop supports safe autocorrection (--autocorrect).
19
88
  # Configuration parameters: Max, AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, AllowedPatterns.
20
89
  # URISchemes: http, https
@@ -24,6 +93,7 @@ Layout/LineLength:
24
93
  - 'lib/lutaml/model/comparable_model.rb'
25
94
  - 'lib/lutaml/model/serialize.rb'
26
95
  - 'lib/lutaml/model/type.rb'
96
+ - 'lib/lutaml/model/utils.rb'
27
97
  - 'lib/lutaml/model/xml_adapter/nokogiri_adapter.rb'
28
98
  - 'lib/lutaml/model/xml_adapter/ox_adapter.rb'
29
99
  - 'lib/lutaml/model/xml_adapter/xml_document.rb'
@@ -33,6 +103,17 @@ Layout/LineLength:
33
103
  - 'spec/lutaml/model/schema/json_schema_spec.rb'
34
104
  - 'spec/lutaml/model/serializable_spec.rb'
35
105
 
106
+ # Offense count: 24
107
+ # This cop supports safe autocorrection (--autocorrect).
108
+ # Configuration parameters: AllowInHeredoc.
109
+ Layout/TrailingWhitespace:
110
+ Exclude:
111
+ - 'lib/lutaml/model/serialize.rb'
112
+ - 'lib/lutaml/model/xml_adapter/nokogiri_adapter.rb'
113
+ - 'lib/lutaml/model/xml_adapter/ox_adapter.rb'
114
+ - 'lib/lutaml/model/xml_adapter/xml_document.rb'
115
+ - 'spec/lutaml/model/serializable_spec.rb'
116
+
36
117
  # Offense count: 4
37
118
  # Configuration parameters: AllowedMethods.
38
119
  # AllowedMethods: enums
@@ -43,7 +124,7 @@ Lint/ConstantDefinitionInBlock:
43
124
  - 'spec/lutaml/model/schema/xsd_schema_spec.rb'
44
125
  - 'spec/lutaml/model/schema/yaml_schema_spec.rb'
45
126
 
46
- # Offense count: 31
127
+ # Offense count: 28
47
128
  # Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes, Max.
48
129
  Metrics/AbcSize:
49
130
  Exclude:
@@ -56,13 +137,13 @@ Metrics/AbcSize:
56
137
  - 'lib/lutaml/model/xml_adapter/ox_adapter.rb'
57
138
  - 'lib/lutaml/model/xml_adapter/xml_document.rb'
58
139
 
59
- # Offense count: 4
140
+ # Offense count: 5
60
141
  # Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns, inherit_mode.
61
142
  # AllowedMethods: refine
62
143
  Metrics/BlockLength:
63
- Max: 31
144
+ Max: 29
64
145
 
65
- # Offense count: 23
146
+ # Offense count: 20
66
147
  # Configuration parameters: AllowedMethods, AllowedPatterns, Max.
67
148
  Metrics/CyclomaticComplexity:
68
149
  Exclude:
@@ -73,23 +154,22 @@ Metrics/CyclomaticComplexity:
73
154
  - 'lib/lutaml/model/xml_adapter/ox_adapter.rb'
74
155
  - 'lib/lutaml/model/xml_adapter/xml_document.rb'
75
156
 
76
- # Offense count: 38
157
+ # Offense count: 37
77
158
  # Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns.
78
159
  Metrics/MethodLength:
79
- Max: 52
160
+ Max: 45
80
161
 
81
162
  # Offense count: 4
82
163
  # Configuration parameters: CountKeywordArgs, MaxOptionalParameters.
83
164
  Metrics/ParameterLists:
84
165
  Max: 9
85
166
 
86
- # Offense count: 20
167
+ # Offense count: 16
87
168
  # Configuration parameters: AllowedMethods, AllowedPatterns, Max.
88
169
  Metrics/PerceivedComplexity:
89
170
  Exclude:
90
171
  - 'lib/lutaml/model/comparable_model.rb'
91
172
  - 'lib/lutaml/model/serialize.rb'
92
- - 'lib/lutaml/model/type.rb'
93
173
  - 'lib/lutaml/model/xml_adapter/nokogiri_adapter.rb'
94
174
  - 'lib/lutaml/model/xml_adapter/ox_adapter.rb'
95
175
  - 'lib/lutaml/model/xml_adapter/xml_document.rb'
@@ -103,7 +183,7 @@ RSpec/ContextWording:
103
183
  - 'spec/lutaml/model/xml_adapter/oga_adapter_spec.rb'
104
184
  - 'spec/lutaml/model/xml_adapter/ox_adapter_spec.rb'
105
185
 
106
- # Offense count: 73
186
+ # Offense count: 76
107
187
  # Configuration parameters: CountAsOne.
108
188
  RSpec/ExampleLength:
109
189
  Max: 57
@@ -132,7 +212,7 @@ RSpec/MultipleDescribes:
132
212
 
133
213
  # Offense count: 70
134
214
  RSpec/MultipleExpectations:
135
- Max: 15
215
+ Max: 10
136
216
 
137
217
  # Offense count: 11
138
218
  # Configuration parameters: AllowSubject.
@@ -159,9 +239,35 @@ Security/CompoundHash:
159
239
  Exclude:
160
240
  - 'lib/lutaml/model/comparable_model.rb'
161
241
 
242
+ # Offense count: 10
243
+ # This cop supports safe autocorrection (--autocorrect).
244
+ # Configuration parameters: EnforcedStyle, ProceduralMethods, FunctionalMethods, AllowedMethods, AllowedPatterns, AllowBracesOnProceduralOneLiners, BracesRequiredMethods.
245
+ # SupportedStyles: line_count_based, semantic, braces_for_chaining, always_braces
246
+ # ProceduralMethods: benchmark, bm, bmbm, create, each_with_object, measure, new, realtime, tap, with_object
247
+ # FunctionalMethods: let, let!, subject, watch
248
+ # AllowedMethods: lambda, proc, it
249
+ Style/BlockDelimiters:
250
+ Exclude:
251
+ - 'lib/lutaml/model/xml_adapter/xml_document.rb'
252
+ - 'spec/lutaml/model/serializable_spec.rb'
253
+
254
+ # Offense count: 2
255
+ # This cop supports safe autocorrection (--autocorrect).
256
+ Style/MultilineIfModifier:
257
+ Exclude:
258
+ - 'lib/lutaml/model/serialize.rb'
259
+
162
260
  # Offense count: 1
163
261
  # Configuration parameters: AllowedMethods.
164
262
  # AllowedMethods: respond_to_missing?
165
263
  Style/OptionalBooleanParameter:
166
264
  Exclude:
167
265
  - 'lib/lutaml/model/comparable_model.rb'
266
+
267
+ # Offense count: 2
268
+ # This cop supports safe autocorrection (--autocorrect).
269
+ # Configuration parameters: EnforcedStyle, ConsistentQuotesInMultiline.
270
+ # SupportedStyles: single_quotes, double_quotes
271
+ Style/StringLiterals:
272
+ Exclude:
273
+ - 'lutaml-model.gemspec'
data/README.adoc CHANGED
@@ -1338,11 +1338,11 @@ class CustomCeramic < Lutaml::Model::Serializable
1338
1338
  end
1339
1339
 
1340
1340
  def name_to_json(model, value)
1341
- "Masterpiece: #{value}"
1341
+ doc["name"] = "Masterpiece: #{value}"
1342
1342
  end
1343
1343
 
1344
1344
  def name_from_json(model, doc)
1345
- doc['name'].sub(/^Masterpiece: /, '')
1345
+ model.name = value.sub(/^JSON Masterpiece: /, '')
1346
1346
  end
1347
1347
  end
1348
1348
  ----
@@ -1971,52 +1971,56 @@ class Example < Lutaml::Model::Serializable
1971
1971
  from: :description_from_xml }
1972
1972
  end
1973
1973
 
1974
- def name_to_json(_model, value)
1975
- "JSON Masterpiece: #{value}"
1974
+ def name_to_json(model, doc)
1975
+ doc["name"] = "JSON Masterpiece: #{model.name}"
1976
1976
  end
1977
1977
 
1978
- def name_from_json(_model, doc)
1979
- doc["name"].sub(/^JSON Masterpiece: /, "")
1978
+ def name_from_json(model, value)
1979
+ model.name = value.sub(/^JSON Masterpiece: /, "")
1980
1980
  end
1981
1981
 
1982
- def color_to_json(_model, value)
1983
- value.upcase
1982
+ def color_to_json(model, doc)
1983
+ doc["color"] = model.color.upcase
1984
1984
  end
1985
1985
 
1986
- def color_from_json(_model, doc)
1987
- doc["color"].downcase
1986
+ def color_from_json(model, value)
1987
+ model.color = value.downcase
1988
1988
  end
1989
1989
 
1990
- def description_to_json(_model, value)
1991
- "JSON Description: #{value}"
1990
+ def description_to_json(model, doc)
1991
+ doc["description"] = "JSON Description: #{model.description}"
1992
1992
  end
1993
1993
 
1994
- def description_from_json(_model, doc)
1995
- doc["description"].sub(/^JSON Description: /, "")
1994
+ def description_from_json(model, value)
1995
+ model.description = value.sub(/^JSON Description: /, "")
1996
1996
  end
1997
1997
 
1998
- def name_to_xml(_model, value)
1999
- "XML Masterpiece: #{value}"
1998
+ def name_to_xml(model, parent, doc)
1999
+ el = doc.create_element("Name")
2000
+ doc.add_text(el, "XML Masterpiece: #{model.name}")
2001
+ doc.add_element(parent, el)
2000
2002
  end
2001
2003
 
2002
- def name_from_xml(_model, value)
2003
- value.sub(/^XML Masterpiece: /, "")
2004
+ def name_from_xml(model, value)
2005
+ model.name = value.sub(/^XML Masterpiece: /, "")
2004
2006
  end
2005
2007
 
2006
- def color_to_xml(_model, value)
2007
- value.upcase
2008
+ def color_to_xml(model, parent, doc)
2009
+ color_element = doc.create_element("Color")
2010
+ doc.add_text(color_element, model.color.upcase)
2011
+ doc.add_element(parent, color_element)
2008
2012
  end
2009
2013
 
2010
- def color_from_xml(_model, value)
2011
- value.downcase
2014
+ def color_from_xml(model, value)
2015
+ model.color = value.downcase
2012
2016
  end
2013
2017
 
2014
- def description_to_xml(_model, value)
2015
- "XML Description: #{value}"
2018
+ def description_to_xml(model, parent, doc)
2019
+ doc.add_text(parent, "XML Description: #{model.description}")
2016
2020
  end
2017
2021
 
2018
- def description_from_xml(_model, value)
2019
- value.sub(/^XML Description: /, "")
2022
+ def description_from_xml(model, value)
2023
+ model.description = value.join.strip.sub(/^XML Description: /, "")
2020
2024
  end
2021
2025
  end
2022
2026
  ----
@@ -40,6 +40,33 @@ module Lutaml
40
40
  def render_nil?
41
41
  options.fetch(:render_nil, false)
42
42
  end
43
+
44
+ def serialize(value, format, options = {})
45
+ if value.is_a?(Array)
46
+ value.map do |v|
47
+ serialize(v, format, options)
48
+ end
49
+ elsif type <= Serialize
50
+ type.hash_representation(value, format, options)
51
+ else
52
+ type.serialize(value)
53
+ end
54
+ end
55
+
56
+ def cast(value, format, options = {})
57
+ value ||= [] if collection?
58
+ instance = options[:instance]
59
+
60
+ if value.is_a?(Array)
61
+ value.map do |v|
62
+ cast(v, format, instance: instance)
63
+ end
64
+ elsif type <= Serialize
65
+ type.apply_mappings(value, format, options)
66
+ else
67
+ Lutaml::Model::Type.cast(value, type)
68
+ end
69
+ end
43
70
  end
44
71
  end
45
72
  end
@@ -85,9 +85,8 @@ module Lutaml
85
85
  define_method(:"from_#{format}") do |data|
86
86
  adapter = Lutaml::Model::Config.send(:"#{format}_adapter")
87
87
  doc = adapter.parse(data)
88
- mapped_attrs = apply_mappings(doc.to_h, format)
89
- # apply_content_mapping(doc, mapped_attrs) if format == :xml
90
- generate_model_object(self, mapped_attrs)
88
+
89
+ apply_mappings(doc.to_h, format)
91
90
  end
92
91
 
93
92
  define_method(:"to_#{format}") do |instance|
@@ -118,13 +117,14 @@ module Lutaml
118
117
  name = rule.to
119
118
  next if except&.include?(name) || (only && !only.include?(name))
120
119
 
121
- next handle_delegate(instance, rule, hash) if rule.delegate
120
+ next handle_delegate(instance, rule, hash, format) if rule.delegate
122
121
 
123
- value = if rule.custom_methods[:to]
124
- instance.send(rule.custom_methods[:to], instance, instance.send(name))
125
- else
126
- instance.send(name)
127
- end
122
+ if rule.custom_methods[:to]
123
+ next instance.send(rule.custom_methods[:to], instance,
124
+ hash)
125
+ end
126
+
127
+ value = instance.send(name)
128
128
 
129
129
  next if value.nil? && !rule.render_nil
130
130
 
@@ -132,68 +132,27 @@ module Lutaml
132
132
 
133
133
  hash[rule.from] = if rule.child_mappings
134
134
  generate_hash_from_child_mappings(value, rule.child_mappings)
135
- elsif value.is_a?(Array)
136
- value.map do |v|
137
- if attribute.type <= Serialize
138
- attribute.type.hash_representation(v, format, options)
139
- else
140
- attribute.type.serialize(v)
141
- end
142
- end
143
- elsif attribute.type <= Serialize
144
- attribute.type.hash_representation(value, format, options)
145
135
  else
146
- attribute.type.serialize(value)
136
+ attribute.serialize(value, format, options)
147
137
  end
148
138
  end
149
139
  end
150
140
 
151
- def handle_delegate(instance, rule, hash)
141
+ def handle_delegate(instance, rule, hash, format)
152
142
  name = rule.to
153
143
  value = instance.send(rule.delegate).send(name)
154
144
  return if value.nil? && !rule.render_nil
155
145
 
156
146
  attribute = instance.send(rule.delegate).class.attributes[name]
157
- hash[rule.from] = case value
158
- when Array
159
- value.map do |v|
160
- if v.is_a?(Serialize)
161
- hash_representation(v, format, options)
162
- else
163
- attribute.type.serialize(v)
164
- end
165
- end
166
- else
167
- if value.is_a?(Serialize)
168
- hash_representation(value, format, options)
169
- else
170
- attribute.type.serialize(value)
171
- end
172
- end
147
+ hash[rule.from] = attribute.serialize(value, format)
173
148
  end
174
149
 
175
150
  def mappings_for(format)
176
151
  mappings[format] || default_mappings(format)
177
152
  end
178
153
 
179
- def generate_model_object(type, mapped_attrs)
180
- return type.model.new(mapped_attrs) if self == model
181
-
182
- instance = type.model.new
183
-
184
- type.attributes.each do |name, attr|
185
- value = attr_value(mapped_attrs, name, attr)
186
-
187
- instance.send(:"#{name}=", ensure_utf8(value))
188
- end
189
-
190
- instance
191
- end
192
-
193
154
  def attr_value(attrs, name, attr_rule)
194
- value = if attrs.key?(name)
195
- attrs[name]
196
- elsif attrs.key?(name.to_sym)
155
+ value = if attrs.key?(name.to_sym)
197
156
  attrs[name.to_sym]
198
157
  elsif attrs.key?(name.to_s)
199
158
  attrs[name.to_s]
@@ -211,8 +170,6 @@ module Lutaml
211
170
  Lutaml::Model::Type.cast(v, attr_rule.type)
212
171
  end
213
172
  end
214
- elsif value.is_a?(Hash) && attr_rule.type != Lutaml::Model::Type::Hash
215
- generate_model_object(attr_rule.type, value)
216
173
  else
217
174
  # TODO: This code is problematic because Type.cast does not know
218
175
  # about all the types.
@@ -279,11 +236,12 @@ module Lutaml
279
236
  hash
280
237
  end
281
238
 
282
- def apply_mappings(doc, format)
283
- return apply_xml_mapping(doc) if format == :xml
239
+ def apply_mappings(doc, format, options = {})
240
+ instance = options[:instance] || model.new
241
+ return apply_xml_mapping(doc, instance, options) if format == :xml
284
242
 
285
243
  mappings = mappings_for(format).mappings
286
- mappings.each_with_object(Lutaml::Model::MappingHash.new) do |rule, hash|
244
+ mappings.each do |rule|
287
245
  attr = if rule.delegate
288
246
  attributes[rule.delegate].type.attributes[rule.to]
289
247
  else
@@ -292,50 +250,51 @@ module Lutaml
292
250
 
293
251
  raise "Attribute '#{rule.to}' not found in #{self}" unless attr
294
252
 
295
- value = if rule.custom_methods[:from]
296
- new.send(rule.custom_methods[:from], hash, doc)
297
- elsif doc.key?(rule.name) || doc.key?(rule.name.to_sym)
253
+ value = if doc.key?(rule.name) || doc.key?(rule.name.to_sym)
298
254
  doc[rule.name] || doc[rule.name.to_sym]
299
255
  else
300
256
  attr.default
301
257
  end
302
258
 
303
- value = apply_child_mappings(value, rule.child_mappings)
304
-
305
- if attr.collection?
306
- value = (value || []).map do |v|
307
- attr.type <= Serialize ? attr.type.apply_mappings(v, format) : v
308
- end
309
- elsif value.is_a?(Hash) && attr.type != Lutaml::Model::Type::Hash
310
- value = attr.type.apply_mappings(value, format)
259
+ if rule.custom_methods[:from]
260
+ value = new.send(rule.custom_methods[:from], instance, value)
261
+ next
311
262
  end
312
263
 
264
+ value = apply_child_mappings(value, rule.child_mappings)
265
+ value = attr.cast(value, format)
266
+
313
267
  if rule.delegate
314
- hash[rule.delegate] ||= {}
315
- hash[rule.delegate][rule.to] = value
268
+ if instance.public_send(rule.delegate).nil?
269
+ instance.public_send(:"#{rule.delegate}=",
270
+ attributes[rule.delegate].type.new)
271
+ end
272
+ instance.public_send(rule.delegate).public_send(:"#{rule.to}=",
273
+ value)
316
274
  else
317
- hash[rule.to] = value
275
+ instance.public_send(:"#{rule.to}=", value)
318
276
  end
319
277
  end
278
+
279
+ instance
320
280
  end
321
281
 
322
- def apply_xml_mapping(doc, caller_class: nil, mixed_content: false)
323
- return unless doc
282
+ def apply_xml_mapping(doc, instance, options = {})
283
+ return instance unless doc
324
284
 
325
285
  mappings = mappings_for(:xml).mappings
326
286
 
327
287
  if doc.is_a?(Array)
328
288
  raise "May be `collection: true` is" \
329
- "missing for #{self} in #{caller_class}"
289
+ "missing for #{self} in #{options[:caller_class]}"
330
290
  end
331
291
 
332
- mapping_hash = Lutaml::Model::MappingHash.new
333
- mapping_hash.item_order = doc.item_order
334
- mapping_hash.ordered = mappings_for(:xml).mixed_content? || mixed_content
335
-
336
- mapping_from = []
292
+ if instance.respond_to?(:ordered=)
293
+ instance.element_order = doc.item_order
294
+ instance.ordered = mappings_for(:xml).mixed_content? || options[:mixed_content]
295
+ end
337
296
 
338
- mappings.each_with_object(mapping_hash) do |rule, hash|
297
+ mappings.each do |rule|
339
298
  attr = attributes[rule.to]
340
299
  raise "Attribute '#{rule.to}' not found in #{self}" unless attr
341
300
 
@@ -346,52 +305,38 @@ module Lutaml
346
305
  doc[rule.name.to_s] || doc[rule.name.to_sym]
347
306
  end
348
307
 
349
- if attr.collection?
350
- if value && !value.is_a?(Array)
351
- value = [value]
352
- end
353
-
354
- value = (value || []).map do |v|
355
- if attr.type <= Serialize
356
- attr.type.apply_xml_mapping(v, caller_class: self, mixed_content: rule.mixed_content)
357
- elsif v.is_a?(Hash)
358
- v["text"]
359
- else
360
- v
361
- end
308
+ if value.is_a?(Array)
309
+ value = value.map do |v|
310
+ v.is_a?(Hash) && !(attr.type <= Serialize) ? v["text"] : v
362
311
  end
363
- elsif attr.type <= Serialize
364
- value = attr.type.apply_xml_mapping(value, caller_class: self, mixed_content: rule.mixed_content)
365
- else
366
- if value.is_a?(Hash) && attr.type != Lutaml::Model::Type::Hash
367
- value = value["text"]
368
- end
369
-
370
- value = attr.type.cast(value) unless is_content_mapping
312
+ elsif !(attr.type <= Serialize) && value.is_a?(Hash) && attr.type != Lutaml::Model::Type::Hash
313
+ value = value["text"]
371
314
  end
372
315
 
373
- mapping_from << rule if rule.custom_methods[:from]
374
-
375
- hash[rule.to] = value
376
- end
377
-
378
- mapping_from.each do |rule|
379
- value = if rule.name.nil?
380
- mapping_hash[rule.to].join("\n").strip
381
- else
382
- mapping_hash[rule.to]
383
- end
316
+ unless is_content_mapping
317
+ value = attr.cast(
318
+ value,
319
+ :xml,
320
+ caller_class: self,
321
+ mixed_content: rule.mixed_content,
322
+ )
323
+ end
384
324
 
385
- mapping_hash[rule.to] = new.send(rule.custom_methods[:from], mapping_hash, value)
325
+ if rule.custom_methods[:from]
326
+ new.send(rule.custom_methods[:from], instance, value)
327
+ else
328
+ instance.public_send(:"#{rule.to}=", value)
329
+ end
386
330
  end
387
331
 
388
- mapping_hash
332
+ instance
389
333
  end
390
334
 
391
335
  def ensure_utf8(value)
392
336
  case value
393
337
  when String
394
- value.encode("UTF-8", invalid: :replace, undef: :replace, replace: "")
338
+ value.encode("UTF-8", invalid: :replace, undef: :replace,
339
+ replace: "")
395
340
  when Array
396
341
  value.map { |v| ensure_utf8(v) }
397
342
  when Hash
@@ -406,7 +351,7 @@ module Lutaml
406
351
  end
407
352
  end
408
353
 
409
- attr_reader :element_order
354
+ attr_accessor :element_order
410
355
 
411
356
  def initialize(attrs = {})
412
357
  return unless self.class.attributes
@@ -429,6 +374,10 @@ module Lutaml
429
374
  @ordered
430
375
  end
431
376
 
377
+ def ordered=(ordered)
378
+ @ordered = ordered
379
+ end
380
+
432
381
  def key_exist?(hash, key)
433
382
  hash.key?(key.to_sym) || hash.key?(key.to_s)
434
383
  end
@@ -444,7 +393,8 @@ module Lutaml
444
393
  representation = if format == :xml
445
394
  self
446
395
  else
447
- self.class.hash_representation(self, format, options)
396
+ self.class.hash_representation(self, format,
397
+ options)
448
398
  end
449
399
 
450
400
  adapter.new(representation).public_send(:"to_#{format}", options)
@@ -455,7 +405,8 @@ module Lutaml
455
405
  self.class.attributes.each do |name, attr|
456
406
  value = send(name)
457
407
  unless self.class.attr_value_valid?(name, value)
458
- raise Lutaml::Model::InvalidValueError.new(name, value, attr.options[:values])
408
+ raise Lutaml::Model::InvalidValueError.new(name, value,
409
+ attr.options[:values])
459
410
  end
460
411
  end
461
412
  end