lutaml-model 0.3.6 → 0.3.8

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: 30487a24277470ff7b3d12193e46262b0fc1cac85461224ed98749c8b6de5104
4
+ data.tar.gz: a161a8e5f83a10ec5db5b77a0d5a0abe72b629d0900a4ab040414c2a02c22725
5
5
  SHA512:
6
- metadata.gz: 37a4e64c1b61b6a1112329b18ea4bd9b544fe125859cd81a1054b162817e1ffb22e03f4168836ce8890e6f6cba6f137c78110522322c0a0fe6fde3e121c533d4
7
- data.tar.gz: bd3bfb6600103c25034c3604fcdc83947d8eb3a14b23ec54e93186f66d273a5270a923394bd5f00e5caf3d58c9ff7c65efce9cd5f7a874ac22f4582711622d27
6
+ metadata.gz: 2a805f81f93bc0dcb983d83e7f7fc870989f84fb25434de7edee18269c1b96b8572516132e17e3db2e188075e985cb8219ec84257fd380c7abfe4b65b32116af
7
+ data.tar.gz: 0243f89d6fb6c5466e29500e810a077096e260b51d53a8a23db7918c7b2d57dc30a9757dd00814a2c497dd552e39bd17e92729c509670dde555a0b508a77013b
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-27 06:48:03 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,7 @@ Gemspec/RequireMFA:
14
14
  Exclude:
15
15
  - 'lutaml-model.gemspec'
16
16
 
17
- # Offense count: 78
17
+ # Offense count: 57
18
18
  # This cop supports safe autocorrection (--autocorrect).
19
19
  # Configuration parameters: Max, AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, AllowedPatterns.
20
20
  # URISchemes: http, https
@@ -24,6 +24,7 @@ Layout/LineLength:
24
24
  - 'lib/lutaml/model/comparable_model.rb'
25
25
  - 'lib/lutaml/model/serialize.rb'
26
26
  - 'lib/lutaml/model/type.rb'
27
+ - 'lib/lutaml/model/utils.rb'
27
28
  - 'lib/lutaml/model/xml_adapter/nokogiri_adapter.rb'
28
29
  - 'lib/lutaml/model/xml_adapter/ox_adapter.rb'
29
30
  - 'lib/lutaml/model/xml_adapter/xml_document.rb'
@@ -43,7 +44,7 @@ Lint/ConstantDefinitionInBlock:
43
44
  - 'spec/lutaml/model/schema/xsd_schema_spec.rb'
44
45
  - 'spec/lutaml/model/schema/yaml_schema_spec.rb'
45
46
 
46
- # Offense count: 31
47
+ # Offense count: 28
47
48
  # Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes, Max.
48
49
  Metrics/AbcSize:
49
50
  Exclude:
@@ -56,16 +57,17 @@ Metrics/AbcSize:
56
57
  - 'lib/lutaml/model/xml_adapter/ox_adapter.rb'
57
58
  - 'lib/lutaml/model/xml_adapter/xml_document.rb'
58
59
 
59
- # Offense count: 4
60
+ # Offense count: 5
60
61
  # Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns, inherit_mode.
61
62
  # AllowedMethods: refine
62
63
  Metrics/BlockLength:
63
- Max: 31
64
+ Max: 43
64
65
 
65
- # Offense count: 23
66
+ # Offense count: 22
66
67
  # Configuration parameters: AllowedMethods, AllowedPatterns, Max.
67
68
  Metrics/CyclomaticComplexity:
68
69
  Exclude:
70
+ - 'lib/lutaml/model/attribute.rb'
69
71
  - 'lib/lutaml/model/comparable_model.rb'
70
72
  - 'lib/lutaml/model/serialize.rb'
71
73
  - 'lib/lutaml/model/type.rb'
@@ -73,23 +75,23 @@ Metrics/CyclomaticComplexity:
73
75
  - 'lib/lutaml/model/xml_adapter/ox_adapter.rb'
74
76
  - 'lib/lutaml/model/xml_adapter/xml_document.rb'
75
77
 
76
- # Offense count: 38
78
+ # Offense count: 36
77
79
  # Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns.
78
80
  Metrics/MethodLength:
79
- Max: 52
81
+ Max: 43
80
82
 
81
83
  # Offense count: 4
82
84
  # Configuration parameters: CountKeywordArgs, MaxOptionalParameters.
83
85
  Metrics/ParameterLists:
84
86
  Max: 9
85
87
 
86
- # Offense count: 20
88
+ # Offense count: 18
87
89
  # Configuration parameters: AllowedMethods, AllowedPatterns, Max.
88
90
  Metrics/PerceivedComplexity:
89
91
  Exclude:
92
+ - 'lib/lutaml/model/attribute.rb'
90
93
  - 'lib/lutaml/model/comparable_model.rb'
91
94
  - 'lib/lutaml/model/serialize.rb'
92
- - 'lib/lutaml/model/type.rb'
93
95
  - 'lib/lutaml/model/xml_adapter/nokogiri_adapter.rb'
94
96
  - 'lib/lutaml/model/xml_adapter/ox_adapter.rb'
95
97
  - 'lib/lutaml/model/xml_adapter/xml_document.rb'
@@ -103,7 +105,7 @@ RSpec/ContextWording:
103
105
  - 'spec/lutaml/model/xml_adapter/oga_adapter_spec.rb'
104
106
  - 'spec/lutaml/model/xml_adapter/ox_adapter_spec.rb'
105
107
 
106
- # Offense count: 73
108
+ # Offense count: 76
107
109
  # Configuration parameters: CountAsOne.
108
110
  RSpec/ExampleLength:
109
111
  Max: 57
@@ -132,7 +134,7 @@ RSpec/MultipleDescribes:
132
134
 
133
135
  # Offense count: 70
134
136
  RSpec/MultipleExpectations:
135
- Max: 15
137
+ Max: 10
136
138
 
137
139
  # Offense count: 11
138
140
  # Configuration parameters: AllowSubject.
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 && value.is_a?(Hash)
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
@@ -84,29 +84,47 @@ module Lutaml
84
84
 
85
85
  define_method(:"from_#{format}") do |data|
86
86
  adapter = Lutaml::Model::Config.send(:"#{format}_adapter")
87
+
87
88
  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)
89
+ public_send(:"of_#{format}", doc.to_h)
91
90
  end
92
91
 
93
- define_method(:"to_#{format}") do |instance|
94
- unless instance.is_a?(model)
95
- msg = "argument is a '#{instance.class}' but should be a '#{model}'"
96
- raise Lutaml::Model::IncorrectModelError, msg
92
+ define_method(:"of_#{format}") do |hash|
93
+ if hash.is_a?(Array)
94
+ return hash.map do |item|
95
+ apply_mappings(item, format)
96
+ end
97
97
  end
98
98
 
99
+ apply_mappings(hash, format)
100
+ end
101
+
102
+ define_method(:"to_#{format}") do |instance|
103
+ value = public_send(:"as_#{format}", instance)
99
104
  adapter = Lutaml::Model::Config.public_send(:"#{format}_adapter")
100
105
 
101
106
  if format == :xml
102
107
  xml_options = { mapper_class: self }
103
-
104
- adapter.new(instance).public_send(:"to_#{format}", xml_options)
108
+ adapter.new(value).public_send(:"to_#{format}", xml_options)
105
109
  else
106
- hash = hash_representation(instance, format)
107
- adapter.new(hash).public_send(:"to_#{format}")
110
+ adapter.new(value).public_send(:"to_#{format}")
108
111
  end
109
112
  end
113
+
114
+ define_method(:"as_#{format}") do |instance|
115
+ if instance.is_a?(Array)
116
+ return instance.map { |item| public_send(:"as_#{format}", item) }
117
+ end
118
+
119
+ unless instance.is_a?(model)
120
+ msg = "argument is a '#{instance.class}' but should be a '#{model}'"
121
+ raise Lutaml::Model::IncorrectModelError, msg
122
+ end
123
+
124
+ return instance if format == :xml
125
+
126
+ hash_representation(instance, format)
127
+ end
110
128
  end
111
129
 
112
130
  def hash_representation(instance, format, options = {})
@@ -118,13 +136,13 @@ module Lutaml
118
136
  name = rule.to
119
137
  next if except&.include?(name) || (only && !only.include?(name))
120
138
 
121
- next handle_delegate(instance, rule, hash) if rule.delegate
139
+ next handle_delegate(instance, rule, hash, format) if rule.delegate
122
140
 
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
141
+ if rule.custom_methods[:to]
142
+ next instance.send(rule.custom_methods[:to], instance, hash)
143
+ end
144
+
145
+ value = instance.send(name)
128
146
 
129
147
  next if value.nil? && !rule.render_nil
130
148
 
@@ -132,68 +150,27 @@ module Lutaml
132
150
 
133
151
  hash[rule.from] = if rule.child_mappings
134
152
  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
153
  else
146
- attribute.type.serialize(value)
154
+ attribute.serialize(value, format, options)
147
155
  end
148
156
  end
149
157
  end
150
158
 
151
- def handle_delegate(instance, rule, hash)
159
+ def handle_delegate(instance, rule, hash, format)
152
160
  name = rule.to
153
161
  value = instance.send(rule.delegate).send(name)
154
162
  return if value.nil? && !rule.render_nil
155
163
 
156
164
  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
165
+ hash[rule.from] = attribute.serialize(value, format)
173
166
  end
174
167
 
175
168
  def mappings_for(format)
176
169
  mappings[format] || default_mappings(format)
177
170
  end
178
171
 
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
172
  def attr_value(attrs, name, attr_rule)
194
- value = if attrs.key?(name)
195
- attrs[name]
196
- elsif attrs.key?(name.to_sym)
173
+ value = if attrs.key?(name.to_sym)
197
174
  attrs[name.to_sym]
198
175
  elsif attrs.key?(name.to_s)
199
176
  attrs[name.to_s]
@@ -211,8 +188,6 @@ module Lutaml
211
188
  Lutaml::Model::Type.cast(v, attr_rule.type)
212
189
  end
213
190
  end
214
- elsif value.is_a?(Hash) && attr_rule.type != Lutaml::Model::Type::Hash
215
- generate_model_object(attr_rule.type, value)
216
191
  else
217
192
  # TODO: This code is problematic because Type.cast does not know
218
193
  # about all the types.
@@ -279,11 +254,13 @@ module Lutaml
279
254
  hash
280
255
  end
281
256
 
282
- def apply_mappings(doc, format)
283
- return apply_xml_mapping(doc) if format == :xml
257
+ def apply_mappings(doc, format, options = {})
258
+ instance = options[:instance] || model.new
259
+ return instance if !doc || doc.empty?
260
+ return apply_xml_mapping(doc, instance, options) if format == :xml
284
261
 
285
262
  mappings = mappings_for(format).mappings
286
- mappings.each_with_object(Lutaml::Model::MappingHash.new) do |rule, hash|
263
+ mappings.each do |rule|
287
264
  attr = if rule.delegate
288
265
  attributes[rule.delegate].type.attributes[rule.to]
289
266
  else
@@ -292,106 +269,96 @@ module Lutaml
292
269
 
293
270
  raise "Attribute '#{rule.to}' not found in #{self}" unless attr
294
271
 
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)
272
+ value = if doc.key?(rule.name) || doc.key?(rule.name.to_sym)
298
273
  doc[rule.name] || doc[rule.name.to_sym]
299
274
  else
300
275
  attr.default
301
276
  end
302
277
 
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)
278
+ if rule.custom_methods[:from]
279
+ value = new.send(rule.custom_methods[:from], instance, value) if value && !value.empty?
280
+ next
311
281
  end
312
282
 
283
+ value = apply_child_mappings(value, rule.child_mappings)
284
+ value = attr.cast(value, format)
285
+
313
286
  if rule.delegate
314
- hash[rule.delegate] ||= {}
315
- hash[rule.delegate][rule.to] = value
287
+ if instance.public_send(rule.delegate).nil?
288
+ instance.public_send(:"#{rule.delegate}=",
289
+ attributes[rule.delegate].type.new)
290
+ end
291
+ instance.public_send(rule.delegate).public_send(:"#{rule.to}=",
292
+ value)
316
293
  else
317
- hash[rule.to] = value
294
+ instance.public_send(:"#{rule.to}=", value)
318
295
  end
319
296
  end
297
+
298
+ instance
320
299
  end
321
300
 
322
- def apply_xml_mapping(doc, caller_class: nil, mixed_content: false)
323
- return unless doc
301
+ def apply_xml_mapping(doc, instance, options = {})
302
+ return instance unless doc
324
303
 
325
304
  mappings = mappings_for(:xml).mappings
326
305
 
327
306
  if doc.is_a?(Array)
328
307
  raise "May be `collection: true` is" \
329
- "missing for #{self} in #{caller_class}"
308
+ "missing for #{self} in #{options[:caller_class]}"
330
309
  end
331
310
 
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 = []
311
+ if instance.respond_to?(:ordered=) && doc.is_a?(Lutaml::Model::MappingHash)
312
+ instance.element_order = doc.item_order
313
+ instance.ordered = mappings_for(:xml).mixed_content? || options[:mixed_content]
314
+ end
337
315
 
338
- mappings.each_with_object(mapping_hash) do |rule, hash|
316
+ mappings.each do |rule|
339
317
  attr = attributes[rule.to]
340
318
  raise "Attribute '#{rule.to}' not found in #{self}" unless attr
341
319
 
342
320
  is_content_mapping = rule.name.nil?
321
+
343
322
  value = if is_content_mapping
344
323
  doc["text"]
345
324
  else
346
325
  doc[rule.name.to_s] || doc[rule.name.to_sym]
347
326
  end
348
327
 
349
- if attr.collection?
350
- if value && !value.is_a?(Array)
351
- value = [value]
352
- end
328
+ value = [value].compact if attr.collection? && !value.is_a?(Array)
353
329
 
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
330
+ if value.is_a?(Array)
331
+ value = value.map do |v|
332
+ v.is_a?(Hash) && !(attr.type <= Serialize) ? v["text"] : v
362
333
  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
334
+ elsif !(attr.type <= Serialize) && value.is_a?(Hash) && attr.type != Lutaml::Model::Type::Hash
335
+ value = value["text"]
371
336
  end
372
337
 
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
338
+ unless is_content_mapping
339
+ value = attr.cast(
340
+ value,
341
+ :xml,
342
+ caller_class: self,
343
+ mixed_content: rule.mixed_content,
344
+ )
345
+ end
384
346
 
385
- mapping_hash[rule.to] = new.send(rule.custom_methods[:from], mapping_hash, value)
347
+ if rule.custom_methods[:from]
348
+ new.send(rule.custom_methods[:from], instance, value)
349
+ else
350
+ instance.public_send(:"#{rule.to}=", value)
351
+ end
386
352
  end
387
353
 
388
- mapping_hash
354
+ instance
389
355
  end
390
356
 
391
357
  def ensure_utf8(value)
392
358
  case value
393
359
  when String
394
- value.encode("UTF-8", invalid: :replace, undef: :replace, replace: "")
360
+ value.encode("UTF-8", invalid: :replace, undef: :replace,
361
+ replace: "")
395
362
  when Array
396
363
  value.map { |v| ensure_utf8(v) }
397
364
  when Hash
@@ -406,7 +373,7 @@ module Lutaml
406
373
  end
407
374
  end
408
375
 
409
- attr_reader :element_order
376
+ attr_accessor :element_order
410
377
 
411
378
  def initialize(attrs = {})
412
379
  return unless self.class.attributes
@@ -429,6 +396,10 @@ module Lutaml
429
396
  @ordered
430
397
  end
431
398
 
399
+ def ordered=(ordered)
400
+ @ordered = ordered
401
+ end
402
+
432
403
  def key_exist?(hash, key)
433
404
  hash.key?(key.to_sym) || hash.key?(key.to_s)
434
405
  end
@@ -444,7 +415,8 @@ module Lutaml
444
415
  representation = if format == :xml
445
416
  self
446
417
  else
447
- self.class.hash_representation(self, format, options)
418
+ self.class.hash_representation(self, format,
419
+ options)
448
420
  end
449
421
 
450
422
  adapter.new(representation).public_send(:"to_#{format}", options)
@@ -455,7 +427,8 @@ module Lutaml
455
427
  self.class.attributes.each do |name, attr|
456
428
  value = send(name)
457
429
  unless self.class.attr_value_valid?(name, value)
458
- raise Lutaml::Model::InvalidValueError.new(name, value, attr.options[:values])
430
+ raise Lutaml::Model::InvalidValueError.new(name, value,
431
+ attr.options[:values])
459
432
  end
460
433
  end
461
434
  end
@@ -22,11 +22,13 @@ module Lutaml
22
22
  class #{t} # class Integer
23
23
  def self.cast(value) # def self.cast(value)
24
24
  return if value.nil? # return if value.nil?
25
+ #
25
26
  Type.cast(value, #{t}) # Type.cast(value, Integer)
26
27
  end # end
27
28
 
28
29
  def self.serialize(value) # def self.serialize(value)
29
30
  return if value.nil? # return if value.nil?
31
+ #
30
32
  Type.serialize(value, #{t}) # Type.serialize(value, Integer)
31
33
  end # end
32
34
  end # end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Lutaml
4
+ module Model
5
+ module Utils
6
+ class << self
7
+ # Convert string to camel case
8
+ def camel_case(str)
9
+ return "" if str.nil? || str.empty?
10
+
11
+ str.split("/").map { |part| camelize_part(part) }.join("::")
12
+ end
13
+
14
+ # Convert string to class name
15
+ def classify(str)
16
+ str = str.to_s.delete(".")
17
+ str = str.sub(/^[a-z\d]*/) { |match| camel_case(match) || match }
18
+
19
+ str.gsub("::", "/").gsub(%r{(?:_|-|(/))([a-z\d]*)}i) do
20
+ word = Regexp.last_match(2)
21
+ substituted = camel_case(word) || word
22
+ Regexp.last_match(1) ? "::#{substituted}" : substituted
23
+ end
24
+ end
25
+
26
+ # Convert string to snake case
27
+ def snake_case(str)
28
+ str = str.to_s.tr(".", "_")
29
+ return str unless /[A-Z-]|::/.match?(str)
30
+
31
+ str.gsub("::", "/")
32
+ .gsub(/([A-Z]+)(?=[A-Z][a-z])|([a-z\d])(?=[A-Z])/) { "#{$1 || $2}_" }
33
+ .tr("-", "_")
34
+ .downcase
35
+ end
36
+
37
+ private
38
+
39
+ def camelize_part(part)
40
+ part.gsub(/(?:_|-|^)([a-z\d])/i) { $1.upcase }
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end