lutaml-model 0.3.10 → 0.3.14
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 +25 -23
- data/Gemfile +1 -0
- data/LICENSE.md +33 -0
- data/README.adoc +200 -15
- data/lib/lutaml/model/attribute.rb +28 -3
- data/lib/lutaml/model/error/incorrect_mapping_argument_error.rb +6 -0
- data/lib/lutaml/model/error/type_not_enabled_error.rb +9 -0
- data/lib/lutaml/model/error.rb +2 -0
- data/lib/lutaml/model/json_adapter/standard_json_adapter.rb +1 -2
- data/lib/lutaml/model/key_value_mapping.rb +25 -1
- data/lib/lutaml/model/key_value_mapping_rule.rb +31 -1
- data/lib/lutaml/model/mapping_hash.rb +22 -0
- data/lib/lutaml/model/mapping_rule.rb +28 -22
- data/lib/lutaml/model/serialize.rb +120 -64
- data/lib/lutaml/model/type.rb +10 -0
- data/lib/lutaml/model/utils.rb +34 -0
- data/lib/lutaml/model/version.rb +1 -1
- data/lib/lutaml/model/xml_adapter/builder/nokogiri.rb +14 -6
- data/lib/lutaml/model/xml_adapter/builder/ox.rb +4 -0
- data/lib/lutaml/model/xml_adapter/nokogiri_adapter.rb +20 -9
- data/lib/lutaml/model/xml_adapter/ox_adapter.rb +9 -1
- data/lib/lutaml/model/xml_adapter/xml_attribute.rb +10 -0
- data/lib/lutaml/model/xml_adapter/xml_document.rb +86 -35
- data/lib/lutaml/model/xml_adapter/xml_element.rb +13 -3
- data/lib/lutaml/model/xml_adapter/xml_namespace.rb +1 -1
- data/lib/lutaml/model/xml_mapping.rb +60 -9
- data/lib/lutaml/model/xml_mapping_rule.rb +64 -4
- data/lib/lutaml/model/yaml_adapter/standard_yaml_adapter.rb +10 -5
- data/lutaml-model.gemspec +0 -1
- metadata +5 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5b36d07a850d4736c0634735a198f05dd34c49b906cd1265b3dd49266931eb22
|
4
|
+
data.tar.gz: cefd0559ad4010ecd2ab0a547ab87493b4958a480f6cb19ab317c248836b8f75
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 83fac7632d0eec4f5bd4339132b36d267877932cf34839eac6dbdefd0cd0e551988b73b3cd379b856af0df351e42694c157342efd8baba67e283e71d34b88171
|
7
|
+
data.tar.gz: 6befe6bfce13fb6175a04f8e0ac81794304d3c56c51feea343334c501346cba517db1f89ab3387ea3300e546d160d24af264048e9762c85debc4063300d57025
|
data/.rubocop_todo.yml
CHANGED
@@ -1,25 +1,18 @@
|
|
1
1
|
# This configuration was generated by
|
2
2
|
# `rubocop --auto-gen-config`
|
3
|
-
# on 2024-
|
3
|
+
# on 2024-10-23 12:15:48 UTC using RuboCop version 1.66.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
|
7
7
|
# versions of RuboCop, may require this file to be generated again.
|
8
8
|
|
9
|
-
# Offense count:
|
9
|
+
# Offense count: 139
|
10
10
|
# This cop supports safe autocorrection (--autocorrect).
|
11
11
|
# Configuration parameters: Max, AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, AllowedPatterns.
|
12
12
|
# URISchemes: http, https
|
13
13
|
Layout/LineLength:
|
14
14
|
Enabled: false
|
15
15
|
|
16
|
-
# Offense count: 1
|
17
|
-
# This cop supports safe autocorrection (--autocorrect).
|
18
|
-
# Configuration parameters: AllowInHeredoc.
|
19
|
-
Layout/TrailingWhitespace:
|
20
|
-
Exclude:
|
21
|
-
- 'lib/lutaml/model/schema_location.rb'
|
22
|
-
|
23
16
|
# Offense count: 11
|
24
17
|
# Configuration parameters: AllowedMethods.
|
25
18
|
# AllowedMethods: enums
|
@@ -37,12 +30,13 @@ Lint/DuplicateMethods:
|
|
37
30
|
Exclude:
|
38
31
|
- 'lib/lutaml/model/attribute.rb'
|
39
32
|
|
40
|
-
# Offense count:
|
33
|
+
# Offense count: 37
|
41
34
|
# Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes, Max.
|
42
35
|
Metrics/AbcSize:
|
43
36
|
Exclude:
|
44
37
|
- 'lib/lutaml/model/attribute.rb'
|
45
38
|
- 'lib/lutaml/model/comparable_model.rb'
|
39
|
+
- 'lib/lutaml/model/mapping_rule.rb'
|
46
40
|
- 'lib/lutaml/model/schema/relaxng_schema.rb'
|
47
41
|
- 'lib/lutaml/model/schema/xsd_schema.rb'
|
48
42
|
- 'lib/lutaml/model/serialize.rb'
|
@@ -50,14 +44,15 @@ Metrics/AbcSize:
|
|
50
44
|
- 'lib/lutaml/model/xml_adapter/nokogiri_adapter.rb'
|
51
45
|
- 'lib/lutaml/model/xml_adapter/ox_adapter.rb'
|
52
46
|
- 'lib/lutaml/model/xml_adapter/xml_document.rb'
|
47
|
+
- 'lib/lutaml/model/xml_mapping_rule.rb'
|
53
48
|
|
54
49
|
# Offense count: 6
|
55
50
|
# Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns, inherit_mode.
|
56
51
|
# AllowedMethods: refine
|
57
52
|
Metrics/BlockLength:
|
58
|
-
Max:
|
53
|
+
Max: 47
|
59
54
|
|
60
|
-
# Offense count:
|
55
|
+
# Offense count: 27
|
61
56
|
# Configuration parameters: AllowedMethods, AllowedPatterns, Max.
|
62
57
|
Metrics/CyclomaticComplexity:
|
63
58
|
Exclude:
|
@@ -69,17 +64,17 @@ Metrics/CyclomaticComplexity:
|
|
69
64
|
- 'lib/lutaml/model/xml_adapter/ox_adapter.rb'
|
70
65
|
- 'lib/lutaml/model/xml_adapter/xml_document.rb'
|
71
66
|
|
72
|
-
# Offense count:
|
67
|
+
# Offense count: 50
|
73
68
|
# Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns.
|
74
69
|
Metrics/MethodLength:
|
75
|
-
Max:
|
70
|
+
Max: 51
|
76
71
|
|
77
72
|
# Offense count: 4
|
78
73
|
# Configuration parameters: CountKeywordArgs, MaxOptionalParameters.
|
79
74
|
Metrics/ParameterLists:
|
80
|
-
Max:
|
75
|
+
Max: 12
|
81
76
|
|
82
|
-
# Offense count:
|
77
|
+
# Offense count: 22
|
83
78
|
# Configuration parameters: AllowedMethods, AllowedPatterns, Max.
|
84
79
|
Metrics/PerceivedComplexity:
|
85
80
|
Exclude:
|
@@ -90,7 +85,7 @@ Metrics/PerceivedComplexity:
|
|
90
85
|
- 'lib/lutaml/model/xml_adapter/ox_adapter.rb'
|
91
86
|
- 'lib/lutaml/model/xml_adapter/xml_document.rb'
|
92
87
|
|
93
|
-
# Offense count:
|
88
|
+
# Offense count: 8
|
94
89
|
# Configuration parameters: Prefixes, AllowedPatterns.
|
95
90
|
# Prefixes: when, with, without
|
96
91
|
RSpec/ContextWording:
|
@@ -99,11 +94,12 @@ RSpec/ContextWording:
|
|
99
94
|
- 'spec/lutaml/model/xml_adapter/oga_adapter_spec.rb'
|
100
95
|
- 'spec/lutaml/model/xml_adapter/ox_adapter_spec.rb'
|
101
96
|
- 'spec/lutaml/model/xml_adapter/xml_namespace_spec.rb'
|
97
|
+
- 'spec/lutaml/model/xml_mapping_spec.rb'
|
102
98
|
|
103
|
-
# Offense count:
|
99
|
+
# Offense count: 109
|
104
100
|
# Configuration parameters: CountAsOne.
|
105
101
|
RSpec/ExampleLength:
|
106
|
-
Max:
|
102
|
+
Max: 54
|
107
103
|
|
108
104
|
# Offense count: 2
|
109
105
|
# Configuration parameters: Max, AllowedIdentifiers, AllowedPatterns.
|
@@ -129,11 +125,11 @@ RSpec/MultipleDescribes:
|
|
129
125
|
- 'spec/lutaml/model/xml_adapter/xml_namespace_spec.rb'
|
130
126
|
- 'spec/lutaml/model/xml_adapter_spec.rb'
|
131
127
|
|
132
|
-
# Offense count:
|
128
|
+
# Offense count: 119
|
133
129
|
RSpec/MultipleExpectations:
|
134
|
-
Max:
|
130
|
+
Max: 14
|
135
131
|
|
136
|
-
# Offense count:
|
132
|
+
# Offense count: 18
|
137
133
|
# Configuration parameters: AllowSubject.
|
138
134
|
RSpec/MultipleMemoizedHelpers:
|
139
135
|
Max: 9
|
@@ -147,18 +143,24 @@ RSpec/PendingWithoutReason:
|
|
147
143
|
- 'spec/lutaml/model/xml_adapter/xml_namespace_spec.rb'
|
148
144
|
- 'spec/lutaml/model/xml_adapter_spec.rb'
|
149
145
|
|
146
|
+
# Offense count: 1
|
147
|
+
RSpec/RemoveConst:
|
148
|
+
Exclude:
|
149
|
+
- 'spec/lutaml/model/type/decimal_spec.rb'
|
150
|
+
|
150
151
|
# Offense count: 2
|
151
152
|
RSpec/RepeatedExampleGroupDescription:
|
152
153
|
Exclude:
|
153
154
|
- 'spec/lutaml/model/collection_spec.rb'
|
154
155
|
|
155
|
-
# Offense count:
|
156
|
+
# Offense count: 2
|
156
157
|
# Configuration parameters: Include, CustomTransform, IgnoreMethods, IgnoreMetadata.
|
157
158
|
# Include: **/*_spec.rb
|
158
159
|
RSpec/SpecFilePathFormat:
|
159
160
|
Exclude:
|
160
161
|
- '**/spec/routing/**/*'
|
161
162
|
- 'spec/lutaml/model/collection_spec.rb'
|
163
|
+
- 'spec/lutaml/model/type/decimal_spec.rb'
|
162
164
|
|
163
165
|
# Offense count: 1
|
164
166
|
Security/CompoundHash:
|
data/Gemfile
CHANGED
data/LICENSE.md
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
Licenses & Copyright
|
2
|
+
====================
|
3
|
+
|
4
|
+
This license file adheres to the formatting guidelines of
|
5
|
+
[readable-licenses](https://github.com/nevir/readable-licenses).
|
6
|
+
|
7
|
+
|
8
|
+
Ribose's BSD 2-Clause License
|
9
|
+
-----------------------------
|
10
|
+
|
11
|
+
Copyright (c) 2024, [Ribose Inc](https://www.ribose.com).
|
12
|
+
All rights reserved.
|
13
|
+
|
14
|
+
Redistribution and use in source and binary forms, with or without modification,
|
15
|
+
are permitted provided that the following conditions are met:
|
16
|
+
|
17
|
+
1. Redistributions of source code must retain the above copyright notice,
|
18
|
+
this list of conditions and the following disclaimer.
|
19
|
+
|
20
|
+
2. Redistributions in binary form must reproduce the above copyright notice,
|
21
|
+
this list of conditions and the following disclaimer in the documentation
|
22
|
+
and/or other materials provided with the distribution.
|
23
|
+
|
24
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
25
|
+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
26
|
+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
27
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
28
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
29
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
30
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
31
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
32
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
33
|
+
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
data/README.adoc
CHANGED
@@ -145,6 +145,8 @@ same class and all their attributes are equal.
|
|
145
145
|
|
146
146
|
=== Supported attribute value types
|
147
147
|
|
148
|
+
==== General types
|
149
|
+
|
148
150
|
Lutaml::Model supports the following attribute types, they can be
|
149
151
|
referred by a string, a symbol, or their class constant.
|
150
152
|
|
@@ -166,12 +168,11 @@ attribute :name_of_attribute, {symbol | string | class}
|
|
166
168
|
| `DateTime` | `:date_time` | `Lutaml::Model::Type::DateTime` | `::DateTime`
|
167
169
|
| `TimeWithoutDate` | `:time_without_date` | `Lutaml::Model::Type::TimeWithoutDate` | `::Time`
|
168
170
|
| `Boolean` | `:boolean` | `Lutaml::Model::Type::Boolean` | `Boolean`
|
169
|
-
| `Decimal` | `:decimal` | `Lutaml::Model::Type::Decimal` | `::BigDecimal`
|
171
|
+
| `Decimal` (optional) | `:decimal` | `Lutaml::Model::Type::Decimal` | `::BigDecimal`
|
170
172
|
| `Hash` | `:hash` | `Lutaml::Model::Type::Hash` | `::Hash`
|
171
173
|
|
172
174
|
|===
|
173
175
|
|
174
|
-
|
175
176
|
.Defining attributes with supported types via symbol, string and class
|
176
177
|
[example]
|
177
178
|
====
|
@@ -198,6 +199,23 @@ end
|
|
198
199
|
----
|
199
200
|
====
|
200
201
|
|
202
|
+
==== (optional) Decimal type
|
203
|
+
|
204
|
+
The `BigDecimal` class is no longer part of the standard Ruby library from Ruby
|
205
|
+
3.4 onwards, hence the `Decimal` type is only enabled when the `bigdecimal`
|
206
|
+
library is loaded.
|
207
|
+
|
208
|
+
This means that the following code needs to be run before using (and parsing)
|
209
|
+
the `Decimal` type:
|
210
|
+
|
211
|
+
[source,ruby]
|
212
|
+
----
|
213
|
+
require 'bigdecimal'
|
214
|
+
----
|
215
|
+
|
216
|
+
If the `bigdecimal` library is not loaded, usage of the `Decimal` type will
|
217
|
+
raise a `Lutaml::Model::TypeNotSupportedError`.
|
218
|
+
|
201
219
|
|
202
220
|
=== Attribute as a collection
|
203
221
|
|
@@ -405,6 +423,51 @@ end
|
|
405
423
|
----
|
406
424
|
====
|
407
425
|
|
426
|
+
=== Attribute as raw string
|
427
|
+
|
428
|
+
An attribute can be set to read the value as raw string for XML, by using the `raw: true` option.
|
429
|
+
|
430
|
+
Syntax:
|
431
|
+
|
432
|
+
[source,ruby]
|
433
|
+
----
|
434
|
+
attribute :name_of_attribute, :string, raw: true
|
435
|
+
----
|
436
|
+
|
437
|
+
.Using the `raw` option to read raw value for an XML attribute
|
438
|
+
[example]
|
439
|
+
====
|
440
|
+
[source,ruby]
|
441
|
+
----
|
442
|
+
class Person < Lutaml::Model::Serializable
|
443
|
+
attribute :name, :string
|
444
|
+
attribute :description, :string, raw: true
|
445
|
+
end
|
446
|
+
----
|
447
|
+
|
448
|
+
For the following xml
|
449
|
+
[source,xml]
|
450
|
+
----
|
451
|
+
<Person>
|
452
|
+
<name>John Doe</name>
|
453
|
+
<description>
|
454
|
+
A <b>fictional person</b> commonly used as a <i>placeholder name</i>.
|
455
|
+
</description>
|
456
|
+
</Person>
|
457
|
+
----
|
458
|
+
|
459
|
+
[source,ruby]
|
460
|
+
----
|
461
|
+
> Person.from_xml(xml)
|
462
|
+
> # <Person:0x0000000107a3ca70
|
463
|
+
@description="\n A <b>fictional person</b> commonly used as a <i>placeholder name</i>.\n ",
|
464
|
+
@element_order=["text", "name", "text", "description", "text"],
|
465
|
+
@name="John Doe",
|
466
|
+
@ordered=nil,
|
467
|
+
@validate_on_set=false>
|
468
|
+
----
|
469
|
+
====
|
470
|
+
|
408
471
|
== Serialization model mappings
|
409
472
|
|
410
473
|
=== General
|
@@ -594,7 +657,7 @@ end
|
|
594
657
|
|
595
658
|
[source,xml]
|
596
659
|
----
|
597
|
-
<example value=12><name>John Doe</name></example>
|
660
|
+
<example value="12"><name>John Doe</name></example>
|
598
661
|
----
|
599
662
|
|
600
663
|
[source,ruby]
|
@@ -604,6 +667,37 @@ end
|
|
604
667
|
> Example.new(value: 12).to_xml
|
605
668
|
> #<example value="12"></example>
|
606
669
|
----
|
670
|
+
|
671
|
+
The map_attribute method does not inherit the root element's namespace. If you need to specify a namespace for an attribute,
|
672
|
+
you must explicitly declare the namespace and prefix in the map_attribute method.
|
673
|
+
[example]
|
674
|
+
====
|
675
|
+
The following class will parse the XML snippet below:
|
676
|
+
|
677
|
+
[source,ruby]
|
678
|
+
----
|
679
|
+
class Attribute < Lutaml::Model::Serializable
|
680
|
+
attribute :value, :integer
|
681
|
+
|
682
|
+
xml do
|
683
|
+
root 'example'
|
684
|
+
map_attribute 'value', to: :value, namespace: "http://www.tech.co/XMI", prefix: "xl"
|
685
|
+
end
|
686
|
+
end
|
687
|
+
----
|
688
|
+
|
689
|
+
[source,xml]
|
690
|
+
----
|
691
|
+
<example xl:value="20" xmlns:xl="http://www.tech.co/XMI"></example>
|
692
|
+
----
|
693
|
+
|
694
|
+
[source,ruby]
|
695
|
+
----
|
696
|
+
> Attribute.from_xml(xml)
|
697
|
+
> #<Attribute:0x0000000109436db8 @value=20>
|
698
|
+
> Attribute.new(value: 20).to_xml
|
699
|
+
> #<example xmlns:xl=\"http://www.tech.co/XMI\" xl:value=\"20\"/>
|
700
|
+
----
|
607
701
|
====
|
608
702
|
|
609
703
|
|
@@ -680,7 +774,7 @@ end
|
|
680
774
|
|
681
775
|
[source,xml]
|
682
776
|
----
|
683
|
-
<example value=12><name>John Doe</name> is my moniker.</example>
|
777
|
+
<example value="12"><name>John Doe</name> is my moniker.</example>
|
684
778
|
----
|
685
779
|
|
686
780
|
[source,ruby]
|
@@ -989,7 +1083,7 @@ end
|
|
989
1083
|
|
990
1084
|
TODO: How to create mixed content from `#new`?
|
991
1085
|
|
992
|
-
|
1086
|
+
[[xml-schema-location]]
|
993
1087
|
==== Automatic support of `xsi:schemaLocation`
|
994
1088
|
|
995
1089
|
The
|
@@ -1444,9 +1538,14 @@ NOTE: The corresponding keyword used by Shale is `receiver:` instead of
|
|
1444
1538
|
|
1445
1539
|
==== Attribute serialization with custom methods
|
1446
1540
|
|
1541
|
+
===== General
|
1542
|
+
|
1447
1543
|
Define custom methods for specific attribute mappings using the `with:` key for
|
1448
1544
|
each serialization mapping block for `from` and `to`.
|
1449
1545
|
|
1546
|
+
|
1547
|
+
===== XML serialization with custom methods
|
1548
|
+
|
1450
1549
|
Syntax:
|
1451
1550
|
|
1452
1551
|
.XML serialization with custom methods
|
@@ -1468,6 +1567,81 @@ xml do
|
|
1468
1567
|
end
|
1469
1568
|
----
|
1470
1569
|
|
1570
|
+
.Using the `with:` key to define custom serialization methods for XML
|
1571
|
+
[example]
|
1572
|
+
====
|
1573
|
+
The following class will parse the XML snippet below:
|
1574
|
+
|
1575
|
+
[source,ruby]
|
1576
|
+
----
|
1577
|
+
class CustomCeramic < Lutaml::Model::Serializable
|
1578
|
+
attribute :name, :string
|
1579
|
+
attribute :size, :integer
|
1580
|
+
attribute :description, :string
|
1581
|
+
|
1582
|
+
xml do
|
1583
|
+
map_element "Name", to: :name, with: { to: :name_to_xml, from: :name_from_xml }
|
1584
|
+
map_attribute "Size", to: :size, with: { to: :size_to_xml, from: :size_from_xml }
|
1585
|
+
map_content with: { to: :description_to_xml, from: :description_from_xml }
|
1586
|
+
end
|
1587
|
+
|
1588
|
+
def name_to_xml(model, parent, doc)
|
1589
|
+
el = doc.create_element("Name")
|
1590
|
+
doc.add_text(el, "XML Masterpiece: #{model.name}")
|
1591
|
+
doc.add_element(parent, el)
|
1592
|
+
end
|
1593
|
+
|
1594
|
+
def name_from_xml(model, value)
|
1595
|
+
model.name = value.sub(/^XML Masterpiece: /, "")
|
1596
|
+
end
|
1597
|
+
|
1598
|
+
def size_to_xml(model, parent, doc)
|
1599
|
+
doc.add_attribute(parent, "Size", model.size + 3)
|
1600
|
+
end
|
1601
|
+
|
1602
|
+
def size_from_xml(model, value)
|
1603
|
+
model.size = value.to_i - 3
|
1604
|
+
end
|
1605
|
+
|
1606
|
+
def description_to_xml(model, parent, doc)
|
1607
|
+
doc.add_text(parent, "XML Description: #{model.description}")
|
1608
|
+
end
|
1609
|
+
|
1610
|
+
def description_from_xml(model, value)
|
1611
|
+
model.description = value.join.strip.sub(/^XML Description: /, "")
|
1612
|
+
end
|
1613
|
+
end
|
1614
|
+
----
|
1615
|
+
|
1616
|
+
[source,xml]
|
1617
|
+
----
|
1618
|
+
<CustomCeramic Size="15">
|
1619
|
+
<Name>XML Masterpiece: Vase</Name>
|
1620
|
+
XML Description: A beautiful ceramic vase
|
1621
|
+
</CustomCeramic>
|
1622
|
+
----
|
1623
|
+
|
1624
|
+
[source,ruby]
|
1625
|
+
----
|
1626
|
+
> CustomCeramic.from_xml(xml)
|
1627
|
+
> #<CustomCeramic:0x0000000108d0e1f8
|
1628
|
+
@element_order=["text", "Name", "text", "Size", "text"],
|
1629
|
+
@name="Masterpiece: Vase",
|
1630
|
+
@ordered=nil,
|
1631
|
+
@size=12,
|
1632
|
+
@description="A beautiful ceramic vase",
|
1633
|
+
@validate_on_set=false>
|
1634
|
+
> puts CustomCeramic.new(name: "Vase", size: 12, description: "A beautiful vase").to_xml
|
1635
|
+
# <CustomCeramic Size="15">
|
1636
|
+
# <Name>XML Masterpiece: Vase</Name>
|
1637
|
+
# XML Description: A beautiful vase
|
1638
|
+
# </CustomCeramic>
|
1639
|
+
----
|
1640
|
+
====
|
1641
|
+
|
1642
|
+
|
1643
|
+
===== Key-value data model serialization with custom methods
|
1644
|
+
|
1471
1645
|
.Key-value data model serialization with custom methods
|
1472
1646
|
[source,ruby]
|
1473
1647
|
----
|
@@ -1524,7 +1698,7 @@ end
|
|
1524
1698
|
|
1525
1699
|
|
1526
1700
|
[[attribute-extraction]]
|
1527
|
-
==== Attribute extraction
|
1701
|
+
==== Attribute extraction (for key-value data models only)
|
1528
1702
|
|
1529
1703
|
NOTE: This feature is for key-value data model serialization only.
|
1530
1704
|
|
@@ -1992,9 +2166,9 @@ differences in implementation.
|
|
1992
2166
|
|
|
1993
2167
|
|
1994
2168
|
| Value types
|
1995
|
-
| `Lutaml::Model::Type` includes: `Integer`, `String`, `Float`, `Boolean`, `Date`, `DateTime`, `Time`, `Hash`.
|
2169
|
+
| `Lutaml::Model::Type` includes: `Integer`, `String`, `Float`, `Boolean`, `Date`, `DateTime`, `Time`, `Decimal`, `Hash`.
|
1996
2170
|
| `Shale::Type` includes: `Integer`, `String`, `Float`, `Boolean`, `Date`, `Time`.
|
1997
|
-
| Lutaml::Model supports
|
2171
|
+
| Lutaml::Model supports additional value types `Decimal`, `DateTime` and `Hash`.
|
1998
2172
|
|
1999
2173
|
| Configuration
|
2000
2174
|
| `Lutaml::Model::Config`
|
@@ -2011,6 +2185,11 @@ differences in implementation.
|
|
2011
2185
|
| XML, YAML, JSON, TOML, CSV
|
2012
2186
|
| Lutaml::Model does not support CSV.
|
2013
2187
|
|
2188
|
+
| Validation
|
2189
|
+
| Supports collection range, fixed values, and custom validation
|
2190
|
+
| Requires implementation
|
2191
|
+
|
|
2192
|
+
|
2014
2193
|
| Adapter support
|
2015
2194
|
| XML (Nokogiri, Ox, Oga), YAML, JSON (JSON, MultiJson), TOML (Toml-rb, Tomlib)
|
2016
2195
|
| XML (Nokogiri, Ox), YAML, JSON (JSON, MultiJson), TOML (Toml-rb, Tomlib), CSV
|
@@ -2042,6 +2221,12 @@ namespace from the root element.
|
|
2042
2221
|
| No.
|
2043
2222
|
|
|
2044
2223
|
|
2224
|
+
| Support for `xsi:schemaLocation`
|
2225
|
+
| Yes. Automatically supports the <<xml-schema-location,`xsi:schemaLocation`>>
|
2226
|
+
attribute for every element.
|
2227
|
+
| Requires manual specification on every XML element that uses it.
|
2228
|
+
|
|
2229
|
+
|
2045
2230
|
4+h| Attribute features
|
2046
2231
|
|
2047
2232
|
| Attribute delegation
|
@@ -2061,7 +2246,6 @@ data models.
|
|
2061
2246
|
| No.
|
2062
2247
|
| Lutaml::Model supports attribute extraction from key-value data models.
|
2063
2248
|
|
2064
|
-
|
2065
2249
|
|===
|
2066
2250
|
|
2067
2251
|
|
@@ -2114,25 +2298,26 @@ Actions:
|
|
2114
2298
|
|
2115
2299
|
=== Step 2: Replace value type definitions
|
2116
2300
|
|
2117
|
-
Value types in `Lutaml::Model` are under the `Lutaml::Model::Type` module
|
2301
|
+
Value types in `Lutaml::Model` are under the `Lutaml::Model::Type` module,
|
2302
|
+
or use the LutaML type symbols.
|
2118
2303
|
|
2119
2304
|
[source,ruby]
|
2120
2305
|
----
|
2121
2306
|
class Example < Lutaml::Model::Serializable
|
2122
|
-
attribute :length,
|
2123
|
-
attribute :description,
|
2307
|
+
attribute :length, :integer
|
2308
|
+
attribute :description, :string
|
2124
2309
|
end
|
2125
2310
|
----
|
2126
2311
|
|
2127
2312
|
[NOTE]
|
2128
2313
|
====
|
2129
|
-
`Lutaml::Model`
|
2314
|
+
`Lutaml::Model` supports specifying predefined value types as strings or
|
2130
2315
|
symbols, which is not supported by Shale.
|
2131
2316
|
|
2132
2317
|
[source,ruby]
|
2133
2318
|
----
|
2134
2319
|
class Example < Lutaml::Model::Serializable
|
2135
|
-
attribute :length,
|
2320
|
+
attribute :length, Lutaml::Model::Type::Integer
|
2136
2321
|
attribute :description, "String"
|
2137
2322
|
end
|
2138
2323
|
----
|
@@ -2369,6 +2554,6 @@ allowing you to shape and structure your data into useful forms.
|
|
2369
2554
|
== License and Copyright
|
2370
2555
|
|
2371
2556
|
This project is licensed under the BSD 2-clause License.
|
2372
|
-
See the LICENSE file for details.
|
2557
|
+
See the link:LICENSE.md[] file for details.
|
2373
2558
|
|
2374
2559
|
Copyright Ribose.
|
@@ -7,6 +7,7 @@ module Lutaml
|
|
7
7
|
@name = name
|
8
8
|
@type = cast_type(type)
|
9
9
|
@options = options
|
10
|
+
@raw = !!options[:raw]
|
10
11
|
|
11
12
|
if collection?
|
12
13
|
validate_collection_range
|
@@ -14,6 +15,10 @@ module Lutaml
|
|
14
15
|
end
|
15
16
|
end
|
16
17
|
|
18
|
+
def delegate
|
19
|
+
@options[:delegate]
|
20
|
+
end
|
21
|
+
|
17
22
|
def cast_type(type)
|
18
23
|
case type
|
19
24
|
when Class
|
@@ -27,6 +32,16 @@ module Lutaml
|
|
27
32
|
raise ArgumentError, "Unknown Lutaml::Model::Type: #{type}"
|
28
33
|
end
|
29
34
|
|
35
|
+
def cast_value(value)
|
36
|
+
return type.cast(value) unless value.is_a?(Array)
|
37
|
+
|
38
|
+
value.map { |v| type.cast(v) }
|
39
|
+
end
|
40
|
+
|
41
|
+
def setter
|
42
|
+
:"#{@name}="
|
43
|
+
end
|
44
|
+
|
30
45
|
def collection?
|
31
46
|
options[:collection] || false
|
32
47
|
end
|
@@ -35,10 +50,20 @@ module Lutaml
|
|
35
50
|
!collection?
|
36
51
|
end
|
37
52
|
|
38
|
-
def
|
39
|
-
|
53
|
+
def raw?
|
54
|
+
@raw
|
55
|
+
end
|
40
56
|
|
41
|
-
|
57
|
+
def default
|
58
|
+
value = if delegate
|
59
|
+
type.attributes[to].default
|
60
|
+
elsif options[:default].is_a?(Proc)
|
61
|
+
options[:default].call
|
62
|
+
else
|
63
|
+
options[:default]
|
64
|
+
end
|
65
|
+
|
66
|
+
cast_value(value)
|
42
67
|
end
|
43
68
|
|
44
69
|
def render_nil?
|
data/lib/lutaml/model/error.rb
CHANGED
@@ -6,6 +6,8 @@ module Lutaml
|
|
6
6
|
end
|
7
7
|
|
8
8
|
require_relative "error/invalid_value_error"
|
9
|
+
require_relative "error/incorrect_mapping_argument_error"
|
9
10
|
require_relative "error/unknown_adapter_type_error"
|
10
11
|
require_relative "error/collection_count_out_of_range_error"
|
11
12
|
require_relative "error/validation_error"
|
13
|
+
require_relative "error/type_not_enabled_error"
|
@@ -11,12 +11,14 @@ module Lutaml
|
|
11
11
|
|
12
12
|
def map(
|
13
13
|
name,
|
14
|
-
to
|
14
|
+
to: nil,
|
15
15
|
render_nil: false,
|
16
16
|
with: {},
|
17
17
|
delegate: nil,
|
18
18
|
child_mappings: nil
|
19
19
|
)
|
20
|
+
validate!(name, to, with)
|
21
|
+
|
20
22
|
@mappings << KeyValueMappingRule.new(
|
21
23
|
name,
|
22
24
|
to: to,
|
@@ -28,6 +30,28 @@ module Lutaml
|
|
28
30
|
end
|
29
31
|
|
30
32
|
alias map_element map
|
33
|
+
|
34
|
+
def validate!(key, to, with)
|
35
|
+
if to.nil? && with.empty?
|
36
|
+
msg = ":to or :with argument is required for mapping '#{key}'"
|
37
|
+
raise IncorrectMappingArgumentsError.new(msg)
|
38
|
+
end
|
39
|
+
|
40
|
+
if !with.empty? && (with[:from].nil? || with[:to].nil?)
|
41
|
+
msg = ":with argument for mapping '#{key}' requires :to and :from keys"
|
42
|
+
raise IncorrectMappingArgumentsError.new(msg)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def deep_dup
|
47
|
+
self.class.new.tap do |new_mapping|
|
48
|
+
new_mapping.instance_variable_set(:@mappings, duplicate_mappings)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def duplicate_mappings
|
53
|
+
@mappings.map(&:deep_dup)
|
54
|
+
end
|
31
55
|
end
|
32
56
|
end
|
33
57
|
end
|