lutaml-model 0.3.3 → 0.3.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop_todo.yml +48 -9
- data/README.adoc +295 -55
- data/exe/lutaml-model +7 -0
- data/lib/lutaml/model/cli.rb +131 -0
- data/lib/lutaml/model/comparable_model.rb +528 -0
- data/lib/lutaml/model/comparable_nil.rb +11 -0
- data/lib/lutaml/model/comparison.rb +15 -0
- data/lib/lutaml/model/schema/json_schema.rb +23 -7
- data/lib/lutaml/model/schema/json_schema_parser.rb +91 -0
- data/lib/lutaml/model/schema/relaxng_schema.rb +42 -12
- data/lib/lutaml/model/schema/xsd_schema.rb +29 -11
- data/lib/lutaml/model/schema/yaml_schema.rb +21 -6
- data/lib/lutaml/model/serializable.rb +2 -0
- data/lib/lutaml/model/serialize.rb +23 -7
- data/lib/lutaml/model/type.rb +0 -8
- data/lib/lutaml/model/version.rb +1 -1
- data/lutaml-model.gemspec +2 -5
- metadata +25 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d80c5eb43638cf5d690c6c59db2fba76ddb8e2fc7252117a3c7933bc566b2607
|
4
|
+
data.tar.gz: d75c694c330c017500dcceb604aaa889633dadb53c7766a4b6310ee3aef1725e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fc9ed09d01c0c19b4038af7de38c3c458f7c200f7b5ae509f4e4cfc2d3abe116ad862168b7d2ffef16e0d5205c67b3a54226b8b826f9859a72ec5d32da00545e
|
7
|
+
data.tar.gz: b4b8348522112cce9236dc7989f30b42df22ac04d6a7459b2fff6ad6c6dc7018d4bd88e97ec9f83ab8b2dcf6d92938d18fcdc882914240d3d53fb16e0ba116d3
|
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-16
|
3
|
+
# on 2024-08-16 11:07:41 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,24 +14,41 @@ Gemspec/RequireMFA:
|
|
14
14
|
Exclude:
|
15
15
|
- 'lutaml-model.gemspec'
|
16
16
|
|
17
|
-
# Offense count:
|
17
|
+
# Offense count: 76
|
18
18
|
# This cop supports safe autocorrection (--autocorrect).
|
19
19
|
# Configuration parameters: Max, AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, AllowedPatterns.
|
20
20
|
# URISchemes: http, https
|
21
21
|
Layout/LineLength:
|
22
22
|
Exclude:
|
23
|
+
- 'lib/lutaml/model/cli.rb'
|
24
|
+
- 'lib/lutaml/model/comparable_model.rb'
|
23
25
|
- 'lib/lutaml/model/serialize.rb'
|
24
26
|
- 'lib/lutaml/model/type.rb'
|
25
27
|
- 'lib/lutaml/model/xml_adapter/nokogiri_adapter.rb'
|
26
28
|
- 'lib/lutaml/model/xml_adapter/ox_adapter.rb'
|
27
29
|
- 'lib/lutaml/model/xml_adapter/xml_document.rb'
|
30
|
+
- 'spec/lutaml/model/comparable_model_spec.rb'
|
28
31
|
- 'spec/lutaml/model/delegation_spec.rb'
|
32
|
+
- 'spec/lutaml/model/schema/json_schema_spec.rb'
|
29
33
|
- 'spec/lutaml/model/serializable_spec.rb'
|
30
34
|
|
31
|
-
# Offense count:
|
35
|
+
# Offense count: 4
|
36
|
+
# Configuration parameters: AllowedMethods.
|
37
|
+
# AllowedMethods: enums
|
38
|
+
Lint/ConstantDefinitionInBlock:
|
39
|
+
Exclude:
|
40
|
+
- 'spec/lutaml/model/schema/json_schema_spec.rb'
|
41
|
+
- 'spec/lutaml/model/schema/relaxng_schema_spec.rb'
|
42
|
+
- 'spec/lutaml/model/schema/xsd_schema_spec.rb'
|
43
|
+
- 'spec/lutaml/model/schema/yaml_schema_spec.rb'
|
44
|
+
|
45
|
+
# Offense count: 31
|
32
46
|
# Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes, Max.
|
33
47
|
Metrics/AbcSize:
|
34
48
|
Exclude:
|
49
|
+
- 'lib/lutaml/model/comparable_model.rb'
|
50
|
+
- 'lib/lutaml/model/schema/relaxng_schema.rb'
|
51
|
+
- 'lib/lutaml/model/schema/xsd_schema.rb'
|
35
52
|
- 'lib/lutaml/model/serialize.rb'
|
36
53
|
- 'lib/lutaml/model/type.rb'
|
37
54
|
- 'lib/lutaml/model/xml_adapter/nokogiri_adapter.rb'
|
@@ -44,17 +61,18 @@ Metrics/AbcSize:
|
|
44
61
|
Metrics/BlockLength:
|
45
62
|
Max: 30
|
46
63
|
|
47
|
-
# Offense count:
|
64
|
+
# Offense count: 23
|
48
65
|
# Configuration parameters: AllowedMethods, AllowedPatterns, Max.
|
49
66
|
Metrics/CyclomaticComplexity:
|
50
67
|
Exclude:
|
68
|
+
- 'lib/lutaml/model/comparable_model.rb'
|
51
69
|
- 'lib/lutaml/model/serialize.rb'
|
52
70
|
- 'lib/lutaml/model/type.rb'
|
53
71
|
- 'lib/lutaml/model/xml_adapter/nokogiri_adapter.rb'
|
54
72
|
- 'lib/lutaml/model/xml_adapter/ox_adapter.rb'
|
55
73
|
- 'lib/lutaml/model/xml_adapter/xml_document.rb'
|
56
74
|
|
57
|
-
# Offense count:
|
75
|
+
# Offense count: 38
|
58
76
|
# Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns.
|
59
77
|
Metrics/MethodLength:
|
60
78
|
Max: 41
|
@@ -64,10 +82,11 @@ Metrics/MethodLength:
|
|
64
82
|
Metrics/ParameterLists:
|
65
83
|
Max: 9
|
66
84
|
|
67
|
-
# Offense count:
|
85
|
+
# Offense count: 20
|
68
86
|
# Configuration parameters: AllowedMethods, AllowedPatterns, Max.
|
69
87
|
Metrics/PerceivedComplexity:
|
70
88
|
Exclude:
|
89
|
+
- 'lib/lutaml/model/comparable_model.rb'
|
71
90
|
- 'lib/lutaml/model/serialize.rb'
|
72
91
|
- 'lib/lutaml/model/type.rb'
|
73
92
|
- 'lib/lutaml/model/xml_adapter/nokogiri_adapter.rb'
|
@@ -83,10 +102,10 @@ RSpec/ContextWording:
|
|
83
102
|
- 'spec/lutaml/model/xml_adapter/oga_adapter_spec.rb'
|
84
103
|
- 'spec/lutaml/model/xml_adapter/ox_adapter_spec.rb'
|
85
104
|
|
86
|
-
# Offense count:
|
105
|
+
# Offense count: 70
|
87
106
|
# Configuration parameters: CountAsOne.
|
88
107
|
RSpec/ExampleLength:
|
89
|
-
Max:
|
108
|
+
Max: 57
|
90
109
|
|
91
110
|
# Offense count: 2
|
92
111
|
# Configuration parameters: Max, AllowedIdentifiers, AllowedPatterns.
|
@@ -94,6 +113,14 @@ RSpec/IndexedLet:
|
|
94
113
|
Exclude:
|
95
114
|
- 'spec/address_spec.rb'
|
96
115
|
|
116
|
+
# Offense count: 12
|
117
|
+
RSpec/LeakyConstantDeclaration:
|
118
|
+
Exclude:
|
119
|
+
- 'spec/lutaml/model/schema/json_schema_spec.rb'
|
120
|
+
- 'spec/lutaml/model/schema/relaxng_schema_spec.rb'
|
121
|
+
- 'spec/lutaml/model/schema/xsd_schema_spec.rb'
|
122
|
+
- 'spec/lutaml/model/schema/yaml_schema_spec.rb'
|
123
|
+
|
97
124
|
# Offense count: 4
|
98
125
|
RSpec/MultipleDescribes:
|
99
126
|
Exclude:
|
@@ -102,7 +129,7 @@ RSpec/MultipleDescribes:
|
|
102
129
|
- 'spec/lutaml/model/xml_adapter/xml_namespace_spec.rb'
|
103
130
|
- 'spec/lutaml/model/xml_adapter_spec.rb'
|
104
131
|
|
105
|
-
# Offense count:
|
132
|
+
# Offense count: 69
|
106
133
|
RSpec/MultipleExpectations:
|
107
134
|
Max: 15
|
108
135
|
|
@@ -125,3 +152,15 @@ RSpec/SpecFilePathFormat:
|
|
125
152
|
Exclude:
|
126
153
|
- '**/spec/routing/**/*'
|
127
154
|
- 'spec/lutaml/model/collection_spec.rb'
|
155
|
+
|
156
|
+
# Offense count: 1
|
157
|
+
Security/CompoundHash:
|
158
|
+
Exclude:
|
159
|
+
- 'lib/lutaml/model/comparable_model.rb'
|
160
|
+
|
161
|
+
# Offense count: 1
|
162
|
+
# Configuration parameters: AllowedMethods.
|
163
|
+
# AllowedMethods: respond_to_missing?
|
164
|
+
Style/OptionalBooleanParameter:
|
165
|
+
Exclude:
|
166
|
+
- 'lib/lutaml/model/comparable_model.rb'
|
data/README.adoc
CHANGED
@@ -69,16 +69,18 @@ Or install it yourself as:
|
|
69
69
|
gem install lutaml-model
|
70
70
|
----
|
71
71
|
|
72
|
-
==
|
72
|
+
== Data model class
|
73
73
|
|
74
|
-
===
|
74
|
+
=== Definition
|
75
|
+
|
76
|
+
==== General
|
75
77
|
|
76
78
|
There are two ways to define a data model in Lutaml::Model:
|
77
79
|
|
78
80
|
* Inheriting from the `Lutaml::Model::Serializable` class
|
79
81
|
* Including the `Lutaml::Model::Serialize` module
|
80
82
|
|
81
|
-
|
83
|
+
==== Definition through inheritance
|
82
84
|
|
83
85
|
The simplest way to define a model is to create a class that inherits from
|
84
86
|
`Lutaml::Model::Serializable`.
|
@@ -90,13 +92,13 @@ The `attribute` class method is used to define attributes.
|
|
90
92
|
require 'lutaml/model'
|
91
93
|
|
92
94
|
class Kiln < Lutaml::Model::Serializable
|
93
|
-
attribute :brand,
|
94
|
-
attribute :capacity,
|
95
|
-
attribute :temperature,
|
95
|
+
attribute :brand, :string
|
96
|
+
attribute :capacity, :integer
|
97
|
+
attribute :temperature, :integer
|
96
98
|
end
|
97
99
|
----
|
98
100
|
|
99
|
-
|
101
|
+
==== Definition through inclusion
|
100
102
|
|
101
103
|
If the model class already has a super class that it inherits from, the model
|
102
104
|
can be extended using the `Lutaml::Model::Serialize` module.
|
@@ -108,12 +110,38 @@ require 'lutaml/model'
|
|
108
110
|
class Kiln < SomeSuperClass
|
109
111
|
include Lutaml::Model::Serialize
|
110
112
|
|
111
|
-
attribute :brand,
|
112
|
-
attribute :capacity,
|
113
|
-
attribute :temperature,
|
113
|
+
attribute :brand, :string
|
114
|
+
attribute :capacity, :integer
|
115
|
+
attribute :temperature, :integer
|
114
116
|
end
|
115
117
|
----
|
116
118
|
|
119
|
+
|
120
|
+
=== Comparison
|
121
|
+
|
122
|
+
A `Serialize` / `Serializable` object can be compared with another object of the
|
123
|
+
same class using the `==` operator. This is implemented through the
|
124
|
+
`ComparableModel` module.
|
125
|
+
|
126
|
+
Two objects are considered equal if they have the same class and all their
|
127
|
+
attributes are equal. This behavior differs from the typical Ruby behavior,
|
128
|
+
where two objects are considered equal only if they have the same object ID.
|
129
|
+
|
130
|
+
NOTE: Two `Serialize` objects will have the same `hash` value if they have the
|
131
|
+
same class and all their attributes are equal.
|
132
|
+
|
133
|
+
[source,ruby]
|
134
|
+
----
|
135
|
+
> a = Kiln.new(brand: 'Kiln 1', capacity: 100, temperature: 1050)
|
136
|
+
> b = Kiln.new(brand: 'Kiln 1', capacity: 100, temperature: 1050)
|
137
|
+
> a == b
|
138
|
+
> # true
|
139
|
+
> a.hash == b.hash
|
140
|
+
> # true
|
141
|
+
----
|
142
|
+
|
143
|
+
|
144
|
+
|
117
145
|
== Defining attributes
|
118
146
|
|
119
147
|
=== Supported attribute value types
|
@@ -160,7 +188,7 @@ class Studio < Lutaml::Model::Serializable
|
|
160
188
|
# The following are equivalent
|
161
189
|
attribute :location, :string
|
162
190
|
attribute :potter, "String"
|
163
|
-
attribute :kiln,
|
191
|
+
attribute :kiln, :string
|
164
192
|
end
|
165
193
|
----
|
166
194
|
|
@@ -196,8 +224,8 @@ attribute :name_of_attribute, Type, collection: true
|
|
196
224
|
[source,ruby]
|
197
225
|
----
|
198
226
|
class Studio < Lutaml::Model::Serializable
|
199
|
-
attribute :location,
|
200
|
-
attribute :potters,
|
227
|
+
attribute :location, :string
|
228
|
+
attribute :potters, :string, collection: true
|
201
229
|
end
|
202
230
|
----
|
203
231
|
|
@@ -224,25 +252,85 @@ Syntax:
|
|
224
252
|
attribute :name_of_attribute, Type, values: [value1, value2, ...]
|
225
253
|
----
|
226
254
|
|
227
|
-
|
255
|
+
The values set inside the `values:` option can be of any type, but they must
|
256
|
+
match the type of the attribute. The values are compared using the `==` operator,
|
257
|
+
so the type must implement the `==` method.
|
258
|
+
|
259
|
+
.Using the `values` directive to define acceptable values for an attribute (basic types)
|
260
|
+
[example]
|
261
|
+
====
|
262
|
+
[source,ruby]
|
263
|
+
----
|
264
|
+
class GlazeTechnique < Lutaml::Model::Serializable
|
265
|
+
attribute :name, :string, values: ["Celadon", "Raku", "Majolica"]
|
266
|
+
end
|
267
|
+
----
|
268
|
+
|
269
|
+
[source,ruby]
|
270
|
+
----
|
271
|
+
> GlazeTechnique.new(name: "Celadon").name
|
272
|
+
> # "Celadon"
|
273
|
+
> GlazeTechnique.new(name: "Raku").name
|
274
|
+
> # "Raku"
|
275
|
+
> GlazeTechnique.new(name: "Majolica").name
|
276
|
+
> # "Majolica"
|
277
|
+
> GlazeTechnique.new(name: "Earthenware").name
|
278
|
+
> # Lutaml::Model::InvalidValueError: Invalid value for attribute 'name'
|
279
|
+
----
|
280
|
+
====
|
281
|
+
|
282
|
+
The values can be Serialize objects, which are compared using the `==`
|
283
|
+
and the `hash` methods through the Lutaml::Model::ComparableModel module.
|
284
|
+
|
285
|
+
|
286
|
+
.Using the `values` directive to define acceptable values for an attribute (Serializable objects)
|
228
287
|
[example]
|
229
288
|
====
|
230
289
|
[source,ruby]
|
231
290
|
----
|
232
291
|
class Ceramic < Lutaml::Model::Serializable
|
233
|
-
attribute :type,
|
234
|
-
|
292
|
+
attribute :type, :string
|
293
|
+
attribute :firing_temperature, :integer
|
294
|
+
end
|
295
|
+
|
296
|
+
class CeramicCollection < Lutaml::Model::Serializable
|
297
|
+
attribute :featured_piece,
|
298
|
+
Ceramic,
|
299
|
+
values: [
|
300
|
+
Ceramic.new(type: "Porcelain", firing_temperature: 1300),
|
301
|
+
Ceramic.new(type: "Stoneware", firing_temperature: 1200),
|
302
|
+
Ceramic.new(type: "Earthenware", firing_temperature: 1000),
|
303
|
+
]
|
235
304
|
end
|
236
305
|
----
|
237
306
|
|
238
307
|
[source,ruby]
|
239
308
|
----
|
240
|
-
> Ceramic.new(type:
|
241
|
-
> # "Porcelain"
|
242
|
-
> Ceramic.new(type:
|
243
|
-
> #
|
244
|
-
|
245
|
-
|
309
|
+
> CeramicCollection.new(featured_piece: Ceramic.new(type: "Porcelain", firing_temperature: 1300)).featured_piece
|
310
|
+
> # Ceramic:0x0000000104ac7240 @type="Porcelain", @firing_temperature=1300
|
311
|
+
> CeramicCollection.new(featured_piece: Ceramic.new(type: "Bone China", firing_temperature: 1300)).featured_piece
|
312
|
+
> # Lutaml::Model::InvalidValueError: Invalid value for attribute 'featured_piece'
|
313
|
+
----
|
314
|
+
====
|
315
|
+
|
316
|
+
Serialize provides a `validate` method that checks if all its attributes have
|
317
|
+
valid values. This is necessary for the case when a value is valid at the
|
318
|
+
component level, but not accepted at the aggregation level.
|
319
|
+
|
320
|
+
If a change has been made at the component level (a nested attribute has
|
321
|
+
changed), the aggregation level needs to call the `validate` method to verify
|
322
|
+
acceptance of the newly updated component.
|
323
|
+
|
324
|
+
.Using the `validate` method to check if all attributes have valid values
|
325
|
+
[example]
|
326
|
+
====
|
327
|
+
[source,ruby]
|
328
|
+
----
|
329
|
+
> collection = CeramicCollection.new(featured_piece: Ceramic.new(type: "Porcelain", firing_temperature: 1300))
|
330
|
+
> collection.featured_piece.firing_temperature = 1400
|
331
|
+
> # No error raised in changed nested attribute
|
332
|
+
> collection.validate
|
333
|
+
> # Lutaml::Model::InvalidValueError: Invalid value for attribute 'featured_piece'
|
246
334
|
----
|
247
335
|
====
|
248
336
|
|
@@ -266,8 +354,8 @@ attribute :name_of_attribute, Type, default: -> { value }
|
|
266
354
|
[source,ruby]
|
267
355
|
----
|
268
356
|
class Glaze < Lutaml::Model::Serializable
|
269
|
-
attribute :color,
|
270
|
-
attribute :temperature,
|
357
|
+
attribute :color, :string, default: -> { 'Clear' }
|
358
|
+
attribute :temperature, :integer, default: -> { 1050 }
|
271
359
|
end
|
272
360
|
----
|
273
361
|
|
@@ -378,7 +466,7 @@ end
|
|
378
466
|
[source,ruby]
|
379
467
|
----
|
380
468
|
class Example < Lutaml::Model::Serializable
|
381
|
-
attribute :name,
|
469
|
+
attribute :name, :string
|
382
470
|
|
383
471
|
xml do
|
384
472
|
root 'example'
|
@@ -458,7 +546,7 @@ The following class will parse the XML snippet below:
|
|
458
546
|
[source,ruby]
|
459
547
|
----
|
460
548
|
class Example < Lutaml::Model::Serializable
|
461
|
-
attribute :value,
|
549
|
+
attribute :value, :integer
|
462
550
|
|
463
551
|
xml do
|
464
552
|
root 'example'
|
@@ -506,7 +594,7 @@ The following class will parse the XML snippet below:
|
|
506
594
|
[source,ruby]
|
507
595
|
----
|
508
596
|
class Example < Lutaml::Model::Serializable
|
509
|
-
attribute :description,
|
597
|
+
attribute :description, :string
|
510
598
|
|
511
599
|
xml do
|
512
600
|
root 'example'
|
@@ -540,9 +628,9 @@ The following class will parse the XML snippet below:
|
|
540
628
|
[source,ruby]
|
541
629
|
----
|
542
630
|
class Example < Lutaml::Model::Serializable
|
543
|
-
attribute :name,
|
544
|
-
attribute :description,
|
545
|
-
attribute :value,
|
631
|
+
attribute :name, :string
|
632
|
+
attribute :description, :string
|
633
|
+
attribute :value, :integer
|
546
634
|
|
547
635
|
xml do
|
548
636
|
root 'example'
|
@@ -590,8 +678,8 @@ end
|
|
590
678
|
[source,ruby]
|
591
679
|
----
|
592
680
|
class Ceramic < Lutaml::Model::Serializable
|
593
|
-
attribute :type,
|
594
|
-
attribute :glaze,
|
681
|
+
attribute :type, :string
|
682
|
+
attribute :glaze, :string
|
595
683
|
|
596
684
|
xml do
|
597
685
|
root 'Ceramic'
|
@@ -644,8 +732,8 @@ In this example, `glz` will be used for `Glaze` if it is added inside the
|
|
644
732
|
[source,ruby]
|
645
733
|
----
|
646
734
|
class Glaze < Lutaml::Model::Serializable
|
647
|
-
attribute :color,
|
648
|
-
attribute :temperature,
|
735
|
+
attribute :color, :string
|
736
|
+
attribute :temperature, :integer
|
649
737
|
|
650
738
|
xml do
|
651
739
|
root 'Glaze'
|
@@ -657,7 +745,7 @@ class Glaze < Lutaml::Model::Serializable
|
|
657
745
|
end
|
658
746
|
|
659
747
|
class Ceramic < Lutaml::Model::Serializable
|
660
|
-
attribute :type,
|
748
|
+
attribute :type, :string
|
661
749
|
attribute :glaze, Glaze
|
662
750
|
|
663
751
|
xml do
|
@@ -711,9 +799,9 @@ In this example, the `Type` element will inherit the namespace from the root.
|
|
711
799
|
[source,ruby]
|
712
800
|
----
|
713
801
|
class Ceramic < Lutaml::Model::Serializable
|
714
|
-
attribute :type,
|
715
|
-
attribute :glaze,
|
716
|
-
attribute :color,
|
802
|
+
attribute :type, :string
|
803
|
+
attribute :glaze, :string
|
804
|
+
attribute :color, :string
|
717
805
|
|
718
806
|
xml do
|
719
807
|
root 'Ceramic'
|
@@ -791,8 +879,8 @@ end
|
|
791
879
|
[source,ruby]
|
792
880
|
----
|
793
881
|
class Paragraph < Lutaml::Model::Serializable
|
794
|
-
attribute :bold,
|
795
|
-
attribute :italic,
|
882
|
+
attribute :bold, :string
|
883
|
+
attribute :italic, :string
|
796
884
|
|
797
885
|
xml do
|
798
886
|
root 'p', mixed: true
|
@@ -835,8 +923,8 @@ end
|
|
835
923
|
[source,ruby]
|
836
924
|
----
|
837
925
|
class Paragraph < Lutaml::Model::Serializable
|
838
|
-
attribute :bold,
|
839
|
-
attribute :italic,
|
926
|
+
attribute :bold, :string
|
927
|
+
attribute :italic, :string
|
840
928
|
|
841
929
|
xml do
|
842
930
|
root 'p'
|
@@ -895,8 +983,8 @@ end
|
|
895
983
|
[source,ruby]
|
896
984
|
----
|
897
985
|
class Example < Lutaml::Model::Serializable
|
898
|
-
attribute :name,
|
899
|
-
attribute :value,
|
986
|
+
attribute :name, :string
|
987
|
+
attribute :value, :integer
|
900
988
|
|
901
989
|
json do
|
902
990
|
map 'name', to: :name
|
@@ -943,8 +1031,8 @@ by referring to a Lutaml::Model class as an attribute class.
|
|
943
1031
|
[source,ruby]
|
944
1032
|
----
|
945
1033
|
class Glaze < Lutaml::Model::Serializable
|
946
|
-
attribute :color,
|
947
|
-
attribute :temperature,
|
1034
|
+
attribute :color, :string
|
1035
|
+
attribute :temperature, :integer
|
948
1036
|
|
949
1037
|
json do
|
950
1038
|
map 'color', to: :color
|
@@ -953,7 +1041,7 @@ class Glaze < Lutaml::Model::Serializable
|
|
953
1041
|
end
|
954
1042
|
|
955
1043
|
class Ceramic < Lutaml::Model::Serializable
|
956
|
-
attribute :type,
|
1044
|
+
attribute :type, :string
|
957
1045
|
attribute :glaze, Glaze
|
958
1046
|
|
959
1047
|
json do
|
@@ -983,6 +1071,158 @@ end
|
|
983
1071
|
----
|
984
1072
|
====
|
985
1073
|
|
1074
|
+
|
1075
|
+
=== Separate serialization model
|
1076
|
+
|
1077
|
+
The `Serialize` module can be used to define only serialization mappings for a
|
1078
|
+
separately defined model (a Ruby class).
|
1079
|
+
|
1080
|
+
Syntax:
|
1081
|
+
|
1082
|
+
[source,ruby]
|
1083
|
+
----
|
1084
|
+
class Foo < Lutaml::Model::Serializable
|
1085
|
+
model {DataModelClass}
|
1086
|
+
|
1087
|
+
# ...
|
1088
|
+
end
|
1089
|
+
----
|
1090
|
+
|
1091
|
+
[example]
|
1092
|
+
.Using the `model` method to define serialization mappings for a separate model
|
1093
|
+
====
|
1094
|
+
[source,ruby]
|
1095
|
+
----
|
1096
|
+
class Ceramic
|
1097
|
+
attr_accessor :type, :glaze
|
1098
|
+
|
1099
|
+
def name
|
1100
|
+
"#{type} with #{glaze}"
|
1101
|
+
end
|
1102
|
+
end
|
1103
|
+
|
1104
|
+
class CeramicSerialization < Lutaml::Model::Serializable
|
1105
|
+
model Ceramic
|
1106
|
+
|
1107
|
+
xml do
|
1108
|
+
map_element 'type', to: :type
|
1109
|
+
map_element 'glaze', to: :glaze
|
1110
|
+
end
|
1111
|
+
end
|
1112
|
+
----
|
1113
|
+
|
1114
|
+
[source,ruby]
|
1115
|
+
----
|
1116
|
+
> Ceramic.new(type: "Porcelain", glaze: "Clear").name
|
1117
|
+
> # "Porcelain with Clear"
|
1118
|
+
> CeramicSerialization.from_xml(xml)
|
1119
|
+
> #<Ceramic:0x0000000104ac7240 @type="Porcelain", @glaze="Clear">
|
1120
|
+
> Ceramic.new(type: "Porcelain", glaze: "Clear").to_xml
|
1121
|
+
> #<Ceramic><type>Porcelain</type><glaze>Clear</glaze></Ceramic>
|
1122
|
+
----
|
1123
|
+
====
|
1124
|
+
|
1125
|
+
|
1126
|
+
=== Rendering empty attributes and collections
|
1127
|
+
|
1128
|
+
By default, empty attributes and collections are not rendered in the output.
|
1129
|
+
|
1130
|
+
To render empty attributes and collections, use the `render_nil` option.
|
1131
|
+
|
1132
|
+
Syntax:
|
1133
|
+
|
1134
|
+
[source,ruby]
|
1135
|
+
----
|
1136
|
+
xml do
|
1137
|
+
map_element 'key_value_model_attribute_name', to: :name_of_attribute, render_nil: true
|
1138
|
+
end
|
1139
|
+
----
|
1140
|
+
|
1141
|
+
[source,ruby]
|
1142
|
+
----
|
1143
|
+
json | yaml | toml do
|
1144
|
+
map 'key_value_model_attribute_name', to: :name_of_attribute, render_nil: true
|
1145
|
+
end
|
1146
|
+
----
|
1147
|
+
|
1148
|
+
.Using the `render_nil` option to render empty attributes
|
1149
|
+
[example]
|
1150
|
+
====
|
1151
|
+
[source,ruby]
|
1152
|
+
----
|
1153
|
+
class Ceramic < Lutaml::Model::Serializable
|
1154
|
+
attribute :type, :string
|
1155
|
+
attribute :glaze, :string
|
1156
|
+
|
1157
|
+
xml do
|
1158
|
+
map_element 'type', to: :type, render_nil: true
|
1159
|
+
map_element 'glaze', to: :glaze
|
1160
|
+
end
|
1161
|
+
|
1162
|
+
json do
|
1163
|
+
map 'type', to: :type, render_nil: true
|
1164
|
+
map 'glaze', to: :glaze
|
1165
|
+
end
|
1166
|
+
end
|
1167
|
+
----
|
1168
|
+
|
1169
|
+
[source,ruby]
|
1170
|
+
----
|
1171
|
+
> Ceramic.new.to_json
|
1172
|
+
> # { 'type': null }
|
1173
|
+
> Ceramic.new(type: "Porcelain", glaze: "Clear").to_json
|
1174
|
+
> # { 'type': 'Porcelain', 'glaze': 'Clear' }
|
1175
|
+
----
|
1176
|
+
|
1177
|
+
[source,ruby]
|
1178
|
+
----
|
1179
|
+
> Ceramic.new.to_xml
|
1180
|
+
> # <Ceramic><type></type></Ceramic>
|
1181
|
+
> Ceramic.new(type: "Porcelain", glaze: "Clear").to_xml
|
1182
|
+
> # <Ceramic><type>Porcelain</type><glaze>Clear</glaze></Ceramic>
|
1183
|
+
----
|
1184
|
+
====
|
1185
|
+
|
1186
|
+
.Using the `render_nil` option to render empty attribute collections
|
1187
|
+
[example]
|
1188
|
+
====
|
1189
|
+
[source,ruby]
|
1190
|
+
----
|
1191
|
+
class Ceramic < Lutaml::Model::Serializable
|
1192
|
+
attribute :type, :string
|
1193
|
+
attribute :glazes, :string, collection: true
|
1194
|
+
|
1195
|
+
xml do
|
1196
|
+
map_element 'type', to: :type, render_nil: true
|
1197
|
+
map_element 'glazes', to: :glazes, render_nil: true
|
1198
|
+
end
|
1199
|
+
|
1200
|
+
json do
|
1201
|
+
map 'type', to: :type, render_nil: true
|
1202
|
+
map 'glazes', to: :glazes, render_nil: true
|
1203
|
+
end
|
1204
|
+
end
|
1205
|
+
----
|
1206
|
+
|
1207
|
+
[source,ruby]
|
1208
|
+
----
|
1209
|
+
> Ceramic.new.to_json
|
1210
|
+
> # { 'type': null, 'glazes': [] }
|
1211
|
+
> Ceramic.new(type: "Porcelain", glazes: ["Clear"]).to_json
|
1212
|
+
> # { 'type': 'Porcelain', 'glazes': ['Clear'] }
|
1213
|
+
----
|
1214
|
+
|
1215
|
+
[source,ruby]
|
1216
|
+
----
|
1217
|
+
> Ceramic.new.to_xml
|
1218
|
+
> # <Ceramic><type></type><glazes></glazes></Ceramic>
|
1219
|
+
> Ceramic.new(type: "Porcelain", glazes: ["Clear"]).to_xml
|
1220
|
+
> # <Ceramic><type>Porcelain</type><glazes>Clear</glazes></Ceramic>
|
1221
|
+
----
|
1222
|
+
====
|
1223
|
+
|
1224
|
+
|
1225
|
+
|
986
1226
|
=== Advanced attribute mapping
|
987
1227
|
|
988
1228
|
==== Attribute mapping delegation
|
@@ -1006,8 +1246,8 @@ The following class will parse the JSON snippet below:
|
|
1006
1246
|
[source,ruby]
|
1007
1247
|
----
|
1008
1248
|
class Glaze < Lutaml::Model::Serializable
|
1009
|
-
attribute :color,
|
1010
|
-
attribute :temperature,
|
1249
|
+
attribute :color, :string
|
1250
|
+
attribute :temperature, :integer
|
1011
1251
|
|
1012
1252
|
json do
|
1013
1253
|
map 'color', to: :color
|
@@ -1016,7 +1256,7 @@ class Glaze < Lutaml::Model::Serializable
|
|
1016
1256
|
end
|
1017
1257
|
|
1018
1258
|
class Ceramic < Lutaml::Model::Serializable
|
1019
|
-
attribute :type,
|
1259
|
+
attribute :type, :string
|
1020
1260
|
attribute :glaze, Glaze
|
1021
1261
|
|
1022
1262
|
json do
|
@@ -1069,8 +1309,8 @@ The following class will parse the JSON snippet below:
|
|
1069
1309
|
[source,ruby]
|
1070
1310
|
----
|
1071
1311
|
class CustomCeramic < Lutaml::Model::Serializable
|
1072
|
-
attribute :name,
|
1073
|
-
attribute :size,
|
1312
|
+
attribute :name, :string
|
1313
|
+
attribute :size, :integer
|
1074
1314
|
|
1075
1315
|
json do
|
1076
1316
|
map 'name', to: :name, with: { to: :name_to_json, from: :name_from_json }
|
@@ -1250,9 +1490,9 @@ A model can be defined for this JSON as follows:
|
|
1250
1490
|
[source,ruby]
|
1251
1491
|
----
|
1252
1492
|
class Schema < Lutaml::Model::Serializable
|
1253
|
-
attribute :id,
|
1254
|
-
attribute :link,
|
1255
|
-
attribute :name,
|
1493
|
+
attribute :id, :string
|
1494
|
+
attribute :link, :string
|
1495
|
+
attribute :name, :string
|
1256
1496
|
end
|
1257
1497
|
|
1258
1498
|
class ChildMappingClass < Lutaml::Model::Serializable
|