lutaml-model 0.3.6 → 0.3.7

Sign up to get free protection for your applications and to get access to all the features.
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