lutaml-model 0.4.0 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop_todo.yml +36 -20
- data/README.adoc +1003 -192
- data/lib/lutaml/model/attribute.rb +6 -2
- data/lib/lutaml/model/error/collection_true_missing_error.rb +16 -0
- data/lib/lutaml/model/error/multiple_mappings_error.rb +6 -0
- data/lib/lutaml/model/error.rb +2 -0
- data/lib/lutaml/model/key_value_mapping.rb +25 -4
- data/lib/lutaml/model/key_value_mapping_rule.rb +16 -3
- data/lib/lutaml/model/loggable.rb +15 -0
- data/lib/lutaml/model/mapping_rule.rb +14 -2
- data/lib/lutaml/model/serialize.rb +114 -64
- data/lib/lutaml/model/type/decimal.rb +5 -0
- data/lib/lutaml/model/version.rb +1 -1
- data/lib/lutaml/model/xml_adapter/builder/nokogiri.rb +1 -0
- data/lib/lutaml/model/xml_adapter/builder/oga.rb +180 -0
- data/lib/lutaml/model/xml_adapter/builder/ox.rb +1 -0
- data/lib/lutaml/model/xml_adapter/oga/document.rb +20 -0
- data/lib/lutaml/model/xml_adapter/oga/element.rb +117 -0
- data/lib/lutaml/model/xml_adapter/oga_adapter.rb +77 -44
- data/lib/lutaml/model/xml_adapter/xml_document.rb +14 -12
- data/lib/lutaml/model/xml_mapping.rb +3 -0
- data/lib/lutaml/model/xml_mapping_rule.rb +13 -4
- data/lib/lutaml/model.rb +1 -0
- data/spec/address_spec.rb +1 -0
- data/spec/fixtures/sample_model.rb +7 -0
- data/spec/lutaml/model/custom_model_spec.rb +47 -1
- data/spec/lutaml/model/included_spec.rb +192 -0
- data/spec/lutaml/model/mixed_content_spec.rb +48 -32
- data/spec/lutaml/model/multiple_mapping_spec.rb +329 -0
- data/spec/lutaml/model/ordered_content_spec.rb +1 -1
- data/spec/lutaml/model/render_nil_spec.rb +3 -0
- data/spec/lutaml/model/root_mappings_spec.rb +297 -0
- data/spec/lutaml/model/serializable_spec.rb +42 -7
- data/spec/lutaml/model/type/boolean_spec.rb +62 -0
- data/spec/lutaml/model/with_child_mapping_spec.rb +182 -0
- data/spec/lutaml/model/xml_adapter/oga_adapter_spec.rb +11 -11
- data/spec/lutaml/model/xml_adapter/xml_namespace_spec.rb +67 -1
- data/spec/lutaml/model/xml_adapter_spec.rb +2 -2
- data/spec/lutaml/model/xml_mapping_spec.rb +32 -9
- data/spec/sample_model_spec.rb +114 -0
- metadata +12 -2
@@ -142,7 +142,7 @@ module Lutaml
|
|
142
142
|
# Use the default value if the value is nil
|
143
143
|
value = default if value.nil?
|
144
144
|
|
145
|
-
valid_value!(value) && valid_collection!(value) && valid_pattern!(value)
|
145
|
+
valid_value!(value) && valid_collection!(value, self) && valid_pattern!(value)
|
146
146
|
end
|
147
147
|
|
148
148
|
def validate_collection_range
|
@@ -169,7 +169,9 @@ module Lutaml
|
|
169
169
|
end
|
170
170
|
end
|
171
171
|
|
172
|
-
def valid_collection!(value)
|
172
|
+
def valid_collection!(value, caller)
|
173
|
+
raise Lutaml::Model::CollectionTrueMissingError.new(name, caller) if value.is_a?(Array) && !collection?
|
174
|
+
|
173
175
|
return true unless collection?
|
174
176
|
|
175
177
|
# Allow nil values for collections during initialization
|
@@ -207,6 +209,8 @@ module Lutaml
|
|
207
209
|
end
|
208
210
|
|
209
211
|
def serialize(value, format, options = {})
|
212
|
+
return if value.nil?
|
213
|
+
|
210
214
|
if value.is_a?(Array)
|
211
215
|
value.map do |v|
|
212
216
|
serialize(v, format, options)
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Lutaml
|
2
|
+
module Model
|
3
|
+
class CollectionTrueMissingError < Error
|
4
|
+
def initialize(attr_name, caller_class)
|
5
|
+
@attr_name = attr_name
|
6
|
+
@caller = caller_class
|
7
|
+
|
8
|
+
super()
|
9
|
+
end
|
10
|
+
|
11
|
+
def to_s
|
12
|
+
"May be `collection: true` is missing for `#{@attr_name}` in #{@caller}"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
data/lib/lutaml/model/error.rb
CHANGED
@@ -14,3 +14,5 @@ require_relative "error/validation_error"
|
|
14
14
|
require_relative "error/type_not_enabled_error"
|
15
15
|
require_relative "error/type_error"
|
16
16
|
require_relative "error/unknown_type_error"
|
17
|
+
require_relative "error/multiple_mappings_error"
|
18
|
+
require_relative "error/collection_true_missing_error"
|
@@ -10,29 +10,38 @@ module Lutaml
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def map(
|
13
|
-
name,
|
13
|
+
name = nil,
|
14
14
|
to: nil,
|
15
15
|
render_nil: false,
|
16
16
|
render_default: false,
|
17
17
|
with: {},
|
18
18
|
delegate: nil,
|
19
|
-
child_mappings: nil
|
19
|
+
child_mappings: nil,
|
20
|
+
root_mappings: nil
|
20
21
|
)
|
21
|
-
|
22
|
+
mapping_name = name_for_mapping(root_mappings, name)
|
23
|
+
validate!(mapping_name, to, with)
|
22
24
|
|
23
25
|
@mappings << KeyValueMappingRule.new(
|
24
|
-
|
26
|
+
mapping_name,
|
25
27
|
to: to,
|
26
28
|
render_nil: render_nil,
|
27
29
|
render_default: render_default,
|
28
30
|
with: with,
|
29
31
|
delegate: delegate,
|
30
32
|
child_mappings: child_mappings,
|
33
|
+
root_mappings: root_mappings,
|
31
34
|
)
|
32
35
|
end
|
33
36
|
|
34
37
|
alias map_element map
|
35
38
|
|
39
|
+
def name_for_mapping(root_mappings, name)
|
40
|
+
return "root_mapping" if root_mappings
|
41
|
+
|
42
|
+
name
|
43
|
+
end
|
44
|
+
|
36
45
|
def validate!(key, to, with)
|
37
46
|
if to.nil? && with.empty?
|
38
47
|
msg = ":to or :with argument is required for mapping '#{key}'"
|
@@ -43,6 +52,14 @@ module Lutaml
|
|
43
52
|
msg = ":with argument for mapping '#{key}' requires :to and :from keys"
|
44
53
|
raise IncorrectMappingArgumentsError.new(msg)
|
45
54
|
end
|
55
|
+
|
56
|
+
validate_mappings(key)
|
57
|
+
end
|
58
|
+
|
59
|
+
def validate_mappings(name)
|
60
|
+
if @mappings.any?(&:root_mapping?) || (name == "root_mapping" && @mappings.any?)
|
61
|
+
raise MultipleMappingsError.new("root_mappings cannot be used with other mappings")
|
62
|
+
end
|
46
63
|
end
|
47
64
|
|
48
65
|
def deep_dup
|
@@ -54,6 +71,10 @@ module Lutaml
|
|
54
71
|
def duplicate_mappings
|
55
72
|
@mappings.map(&:deep_dup)
|
56
73
|
end
|
74
|
+
|
75
|
+
def find_by_to(to)
|
76
|
+
@mappings.find { |m| m.to.to_s == to.to_s }
|
77
|
+
end
|
57
78
|
end
|
58
79
|
end
|
59
80
|
end
|
@@ -3,7 +3,8 @@ require_relative "mapping_rule"
|
|
3
3
|
module Lutaml
|
4
4
|
module Model
|
5
5
|
class KeyValueMappingRule < MappingRule
|
6
|
-
attr_reader :child_mappings
|
6
|
+
attr_reader :child_mappings,
|
7
|
+
:root_mappings
|
7
8
|
|
8
9
|
def initialize(
|
9
10
|
name,
|
@@ -12,7 +13,8 @@ module Lutaml
|
|
12
13
|
render_default: false,
|
13
14
|
with: {},
|
14
15
|
delegate: nil,
|
15
|
-
child_mappings: nil
|
16
|
+
child_mappings: nil,
|
17
|
+
root_mappings: nil
|
16
18
|
)
|
17
19
|
super(
|
18
20
|
name,
|
@@ -20,10 +22,17 @@ module Lutaml
|
|
20
22
|
render_nil: render_nil,
|
21
23
|
render_default: render_default,
|
22
24
|
with: with,
|
23
|
-
delegate: delegate
|
25
|
+
delegate: delegate
|
24
26
|
)
|
25
27
|
|
26
28
|
@child_mappings = child_mappings
|
29
|
+
@root_mappings = root_mappings
|
30
|
+
end
|
31
|
+
|
32
|
+
def hash_mappings
|
33
|
+
return @root_mappings if @root_mappings
|
34
|
+
|
35
|
+
@child_mappings
|
27
36
|
end
|
28
37
|
|
29
38
|
def deep_dup
|
@@ -36,6 +45,10 @@ module Lutaml
|
|
36
45
|
child_mappings: Utils.deep_dup(child_mappings),
|
37
46
|
)
|
38
47
|
end
|
48
|
+
|
49
|
+
def root_mapping?
|
50
|
+
name == "root_mapping"
|
51
|
+
end
|
39
52
|
end
|
40
53
|
end
|
41
54
|
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Lutaml
|
2
|
+
module Model
|
3
|
+
module Loggable
|
4
|
+
def self.included(base)
|
5
|
+
base.define_method :warn_auto_handling do |name|
|
6
|
+
caller_file = File.basename(caller_locations(2, 1)[0].path)
|
7
|
+
caller_line = caller_locations(2, 1)[0].lineno
|
8
|
+
|
9
|
+
str = "[Lutaml::Model] WARN: `#{name}` is handled by default. No need to explecitly define at `#{caller_file}:#{caller_line}`"
|
10
|
+
warn(str)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -16,7 +16,8 @@ module Lutaml
|
|
16
16
|
render_default: false,
|
17
17
|
with: {},
|
18
18
|
attribute: false,
|
19
|
-
delegate: nil
|
19
|
+
delegate: nil,
|
20
|
+
root_mappings: nil
|
20
21
|
)
|
21
22
|
@name = name
|
22
23
|
@to = to
|
@@ -25,6 +26,7 @@ module Lutaml
|
|
25
26
|
@custom_methods = with
|
26
27
|
@attribute = attribute
|
27
28
|
@delegate = delegate
|
29
|
+
@root_mappings = root_mappings
|
28
30
|
end
|
29
31
|
|
30
32
|
alias from name
|
@@ -42,6 +44,8 @@ module Lutaml
|
|
42
44
|
if delegate
|
43
45
|
model.public_send(delegate).public_send(to)
|
44
46
|
else
|
47
|
+
return if to.nil?
|
48
|
+
|
45
49
|
model.public_send(to)
|
46
50
|
end
|
47
51
|
end
|
@@ -56,7 +60,7 @@ module Lutaml
|
|
56
60
|
|
57
61
|
def deserialize(model, value, attributes, mapper_class = nil)
|
58
62
|
if custom_methods[:from]
|
59
|
-
mapper_class.new.send(custom_methods[:from], model, value)
|
63
|
+
mapper_class.new.send(custom_methods[:from], model, value) unless value.nil?
|
60
64
|
elsif delegate
|
61
65
|
if model.public_send(delegate).nil?
|
62
66
|
model.public_send(:"#{delegate}=", attributes[delegate].type.new)
|
@@ -68,6 +72,14 @@ module Lutaml
|
|
68
72
|
end
|
69
73
|
end
|
70
74
|
|
75
|
+
def using_custom_methods?
|
76
|
+
!custom_methods.empty?
|
77
|
+
end
|
78
|
+
|
79
|
+
def multiple_mappings?
|
80
|
+
name.is_a?(Array)
|
81
|
+
end
|
82
|
+
|
71
83
|
def deep_dup
|
72
84
|
raise NotImplementedError, "Subclasses must implement `deep_dup`."
|
73
85
|
end
|
@@ -21,6 +21,7 @@ module Lutaml
|
|
21
21
|
|
22
22
|
def self.included(base)
|
23
23
|
base.extend(ClassMethods)
|
24
|
+
base.initialize_attrs(base)
|
24
25
|
end
|
25
26
|
|
26
27
|
module ClassMethods
|
@@ -28,14 +29,18 @@ module Lutaml
|
|
28
29
|
|
29
30
|
def inherited(subclass)
|
30
31
|
super
|
32
|
+
subclass.initialize_attrs(self)
|
33
|
+
end
|
31
34
|
|
32
|
-
|
33
|
-
|
35
|
+
def included(base)
|
36
|
+
base.extend(ClassMethods)
|
37
|
+
base.initialize_attrs(self)
|
38
|
+
end
|
34
39
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
40
|
+
def initialize_attrs(source_class)
|
41
|
+
@mappings = Utils.deep_dup(source_class.instance_variable_get(:@mappings)) || {}
|
42
|
+
@attributes = Utils.deep_dup(source_class.instance_variable_get(:@attributes)) || {}
|
43
|
+
instance_variable_set(:@model, self)
|
39
44
|
end
|
40
45
|
|
41
46
|
def model(klass = nil)
|
@@ -264,15 +269,20 @@ module Lutaml
|
|
264
269
|
|
265
270
|
value = instance.send(name)
|
266
271
|
|
267
|
-
next if Utils.blank?(value) && !rule.render_nil
|
268
|
-
|
269
272
|
attribute = attributes[name]
|
270
273
|
|
271
|
-
hash
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
274
|
+
next hash.merge!(generate_hash_from_child_mappings(value, format, rule.root_mappings)) if rule.root_mapping?
|
275
|
+
|
276
|
+
value = if rule.child_mappings
|
277
|
+
generate_hash_from_child_mappings(value, format, rule.child_mappings)
|
278
|
+
else
|
279
|
+
attribute.serialize(value, format, options)
|
280
|
+
end
|
281
|
+
|
282
|
+
next if Utils.blank?(value) && !rule.render_nil
|
283
|
+
|
284
|
+
rule_from_name = rule.multiple_mappings? ? rule.from.first.to_s : rule.from.to_s
|
285
|
+
hash[rule_from_name] = value
|
276
286
|
end
|
277
287
|
end
|
278
288
|
|
@@ -282,39 +292,14 @@ module Lutaml
|
|
282
292
|
return if value.nil? && !rule.render_nil
|
283
293
|
|
284
294
|
attribute = instance.send(rule.delegate).class.attributes[name]
|
285
|
-
|
295
|
+
rule_from_name = rule.multiple_mappings? ? rule.from.first.to_s : rule.from.to_s
|
296
|
+
hash[rule_from_name] = attribute.serialize(value, format)
|
286
297
|
end
|
287
298
|
|
288
299
|
def mappings_for(format)
|
289
300
|
mappings[format] || default_mappings(format)
|
290
301
|
end
|
291
302
|
|
292
|
-
def attr_value(attrs, name, attr_rule)
|
293
|
-
value = if attrs.key?(name.to_sym)
|
294
|
-
attrs[name.to_sym]
|
295
|
-
elsif attrs.key?(name.to_s)
|
296
|
-
attrs[name.to_s]
|
297
|
-
else
|
298
|
-
attr_rule.default
|
299
|
-
end
|
300
|
-
|
301
|
-
if attr_rule.collection? || value.is_a?(Array)
|
302
|
-
(value || []).map do |v|
|
303
|
-
if v.is_a?(Hash)
|
304
|
-
attr_rule.type.new(v)
|
305
|
-
else
|
306
|
-
# TODO: This code is problematic because Type.cast does not know
|
307
|
-
# about all the types.
|
308
|
-
Lutaml::Model::Type.cast(v, attr_rule.type)
|
309
|
-
end
|
310
|
-
end
|
311
|
-
else
|
312
|
-
# TODO: This code is problematic because Type.cast does not know
|
313
|
-
# about all the types.
|
314
|
-
Lutaml::Model::Type.cast(value, attr_rule.type)
|
315
|
-
end
|
316
|
-
end
|
317
|
-
|
318
303
|
def default_mappings(format)
|
319
304
|
klass = format == :xml ? XmlMapping : KeyValueMapping
|
320
305
|
|
@@ -330,11 +315,11 @@ module Lutaml
|
|
330
315
|
end
|
331
316
|
end
|
332
317
|
|
333
|
-
def
|
318
|
+
def translate_mappings(hash, child_mappings, attr, format)
|
334
319
|
return hash unless child_mappings
|
335
320
|
|
336
321
|
hash.map do |key, value|
|
337
|
-
child_mappings.to_h do |attr_name, path|
|
322
|
+
child_hash = child_mappings.to_h do |attr_name, path|
|
338
323
|
attr_value = if path == :key
|
339
324
|
key
|
340
325
|
elsif path == :value
|
@@ -344,32 +329,59 @@ module Lutaml
|
|
344
329
|
value.dig(*path.map(&:to_s))
|
345
330
|
end
|
346
331
|
|
347
|
-
|
332
|
+
attr_rule = attr.type.mappings_for(format).find_by_to(attr_name)
|
333
|
+
[attr_rule.from.to_s, attr_value]
|
348
334
|
end
|
335
|
+
|
336
|
+
if child_mappings.values == [:key] && hash.values.all?(Hash)
|
337
|
+
child_hash.merge!(value)
|
338
|
+
end
|
339
|
+
|
340
|
+
attr.type.apply_hash_mapping(
|
341
|
+
child_hash,
|
342
|
+
attr.type.model.new,
|
343
|
+
format,
|
344
|
+
{ mappings: attr.type.mappings_for(format).mappings },
|
345
|
+
)
|
349
346
|
end
|
350
347
|
end
|
351
348
|
|
352
|
-
def generate_hash_from_child_mappings(value, child_mappings)
|
349
|
+
def generate_hash_from_child_mappings(value, format, child_mappings)
|
353
350
|
return value unless child_mappings
|
354
351
|
|
355
352
|
hash = {}
|
356
353
|
|
354
|
+
if child_mappings.values == [:key]
|
355
|
+
klass = value.first.class
|
356
|
+
mappings = klass.mappings_for(format)
|
357
|
+
|
358
|
+
klass.attributes.each_key do |name|
|
359
|
+
next if child_mappings.key?(name.to_sym) || child_mappings.key?(name.to_s)
|
360
|
+
|
361
|
+
child_mappings[name.to_sym] = mappings.find_by_to(name)&.name.to_s || name.to_s
|
362
|
+
end
|
363
|
+
end
|
364
|
+
|
357
365
|
value.each do |child_obj|
|
358
366
|
map_key = nil
|
359
367
|
map_value = {}
|
360
368
|
child_mappings.each do |attr_name, path|
|
369
|
+
attr_value = child_obj.send(attr_name)
|
370
|
+
attr_value = attr_value.to_yaml_hash if attr_value.is_a?(Lutaml::Model::Serialize)
|
371
|
+
|
361
372
|
if path == :key
|
362
|
-
map_key =
|
373
|
+
map_key = attr_value
|
363
374
|
elsif path == :value
|
364
|
-
map_value =
|
375
|
+
map_value = attr_value
|
365
376
|
else
|
366
377
|
path = [path] unless path.is_a?(Array)
|
367
378
|
path[0...-1].inject(map_value) do |acc, k|
|
368
379
|
acc[k.to_s] ||= {}
|
369
|
-
end.public_send(:[]=, path.last.to_s,
|
380
|
+
end.public_send(:[]=, path.last.to_s, attr_value)
|
370
381
|
end
|
371
382
|
end
|
372
383
|
|
384
|
+
map_value = nil if map_value.empty?
|
373
385
|
hash[map_key] = map_value
|
374
386
|
end
|
375
387
|
|
@@ -397,12 +409,15 @@ module Lutaml
|
|
397
409
|
def apply_mappings(doc, format, options = {})
|
398
410
|
instance = options[:instance] || model.new
|
399
411
|
return instance if Utils.blank?(doc)
|
412
|
+
|
413
|
+
options[:mappings] = mappings_for(format).mappings
|
400
414
|
return apply_xml_mapping(doc, instance, options) if format == :xml
|
401
415
|
|
402
416
|
apply_hash_mapping(doc, instance, format, options)
|
403
417
|
end
|
404
418
|
|
405
419
|
def apply_xml_mapping(doc, instance, options = {})
|
420
|
+
options = Utils.deep_dup(options)
|
406
421
|
instance.encoding = options[:encoding]
|
407
422
|
return instance unless doc
|
408
423
|
|
@@ -410,11 +425,10 @@ module Lutaml
|
|
410
425
|
options[:default_namespace] =
|
411
426
|
mappings_for(:xml)&.namespace_uri
|
412
427
|
end
|
413
|
-
mappings = mappings_for(:xml).mappings
|
428
|
+
mappings = options[:mappings] || mappings_for(:xml).mappings
|
414
429
|
|
415
430
|
if doc.is_a?(Array)
|
416
|
-
raise
|
417
|
-
"missing for #{self} in #{options[:caller_class]}"
|
431
|
+
raise Lutaml::Model::CollectionTrueMissingError(self, option[:caller_class])
|
418
432
|
end
|
419
433
|
|
420
434
|
if instance.respond_to?(:ordered=) && doc.is_a?(Lutaml::Model::MappingHash)
|
@@ -438,17 +452,18 @@ module Lutaml
|
|
438
452
|
|
439
453
|
attr = attribute_for_rule(rule)
|
440
454
|
|
455
|
+
namespaced_names = rule.namespaced_names(options[:default_namespace])
|
456
|
+
|
441
457
|
value = if rule.raw_mapping?
|
442
458
|
doc.node.inner_xml
|
443
459
|
elsif rule.content_mapping?
|
444
460
|
doc[rule.content_key]
|
445
|
-
elsif doc.
|
446
|
-
doc
|
461
|
+
elsif key = (namespaced_names & doc.keys).first
|
462
|
+
doc[key]
|
447
463
|
else
|
448
464
|
defaults_used << rule.to
|
449
465
|
attr&.default || rule.to_value_for(instance)
|
450
466
|
end
|
451
|
-
|
452
467
|
value = normalize_xml_value(value, rule, attr, options)
|
453
468
|
rule.deserialize(instance, value, attributes, self)
|
454
469
|
end
|
@@ -460,20 +475,28 @@ module Lutaml
|
|
460
475
|
instance
|
461
476
|
end
|
462
477
|
|
463
|
-
def apply_hash_mapping(doc, instance, format,
|
464
|
-
mappings = mappings_for(format).mappings
|
478
|
+
def apply_hash_mapping(doc, instance, format, options = {})
|
479
|
+
mappings = options[:mappings] || mappings_for(format).mappings
|
465
480
|
mappings.each do |rule|
|
466
481
|
raise "Attribute '#{rule.to}' not found in #{self}" unless valid_rule?(rule)
|
467
482
|
|
468
483
|
attr = attribute_for_rule(rule)
|
469
484
|
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
485
|
+
names = rule.multiple_mappings? ? rule.name : [rule.name]
|
486
|
+
|
487
|
+
value = names.collect do |rule_name|
|
488
|
+
if rule.root_mapping?
|
489
|
+
doc
|
490
|
+
elsif doc.key?(rule_name.to_s)
|
491
|
+
doc[rule_name.to_s]
|
492
|
+
elsif doc.key?(rule_name.to_sym)
|
493
|
+
doc[rule_name.to_sym]
|
494
|
+
else
|
495
|
+
attr&.default
|
496
|
+
end
|
497
|
+
end.compact.first
|
475
498
|
|
476
|
-
if rule.
|
499
|
+
if rule.using_custom_methods?
|
477
500
|
if Utils.present?(value)
|
478
501
|
value = new.send(rule.custom_methods[:from], instance, value)
|
479
502
|
end
|
@@ -481,8 +504,9 @@ module Lutaml
|
|
481
504
|
next
|
482
505
|
end
|
483
506
|
|
484
|
-
value =
|
485
|
-
value = attr.cast(value, format)
|
507
|
+
value = translate_mappings(value, rule.hash_mappings, attr, format)
|
508
|
+
value = attr.cast(value, format) unless rule.hash_mappings
|
509
|
+
attr.valid_collection!(value, self)
|
486
510
|
|
487
511
|
rule.deserialize(instance, value, attributes, self)
|
488
512
|
end
|
@@ -567,7 +591,7 @@ module Lutaml
|
|
567
591
|
|
568
592
|
self.class.attributes.each do |name, attr|
|
569
593
|
value = if attrs.key?(name) || attrs.key?(name.to_s)
|
570
|
-
|
594
|
+
attr_value(attrs, name, attr)
|
571
595
|
else
|
572
596
|
using_default_for(name)
|
573
597
|
attr.default
|
@@ -584,6 +608,32 @@ module Lutaml
|
|
584
608
|
end
|
585
609
|
end
|
586
610
|
|
611
|
+
def attr_value(attrs, name, attr_rule)
|
612
|
+
value = if attrs.key?(name.to_sym)
|
613
|
+
attrs[name.to_sym]
|
614
|
+
elsif attrs.key?(name.to_s)
|
615
|
+
attrs[name.to_s]
|
616
|
+
else
|
617
|
+
attr_rule.default
|
618
|
+
end
|
619
|
+
|
620
|
+
if attr_rule.collection? || value.is_a?(Array)
|
621
|
+
(value || []).map do |v|
|
622
|
+
if v.is_a?(Hash)
|
623
|
+
attr_rule.type.new(v)
|
624
|
+
else
|
625
|
+
# TODO: This code is problematic because Type.cast does not know
|
626
|
+
# about all the types.
|
627
|
+
Lutaml::Model::Type.cast(v, attr_rule.type)
|
628
|
+
end
|
629
|
+
end
|
630
|
+
else
|
631
|
+
# TODO: This code is problematic because Type.cast does not know
|
632
|
+
# about all the types.
|
633
|
+
Lutaml::Model::Type.cast(value, attr_rule.type)
|
634
|
+
end
|
635
|
+
end
|
636
|
+
|
587
637
|
def using_default_for(attribute_name)
|
588
638
|
@using_default[attribute_name] = true
|
589
639
|
end
|
data/lib/lutaml/model/version.rb
CHANGED