lutaml-model 0.3.10 → 0.3.14

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: 5140f93f22f4b05222edc408aeca50552082e447b71fddd724b34ba9e6b82d55
4
- data.tar.gz: 0aa44a3c72b65cca0ed2b7411614d8cdb0c44b4e8293e183935cb45ba7818d7c
3
+ metadata.gz: 5b36d07a850d4736c0634735a198f05dd34c49b906cd1265b3dd49266931eb22
4
+ data.tar.gz: cefd0559ad4010ecd2ab0a547ab87493b4958a480f6cb19ab317c248836b8f75
5
5
  SHA512:
6
- metadata.gz: 69e4d0d0a3a5bd19e11a43fd33e03566ca035d18cf948a0a2fc5abe5f880489e4a6ad347d8118a04c35c8c95be5b7eb29ca93d426643c7790ab045db2b34721c
7
- data.tar.gz: df1699ba6647f53f97735d0986b92bf8f76d6bf44430117406100b257f5934ac4a7baa6a4243bb8384db277ecb975bf64efe2f1a16b293739b245150e800cb15
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-09-10 23:53:08 UTC using RuboCop version 1.66.1.
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: 88
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: 31
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: 42
53
+ Max: 47
59
54
 
60
- # Offense count: 25
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: 39
67
+ # Offense count: 50
73
68
  # Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns.
74
69
  Metrics/MethodLength:
75
- Max: 49
70
+ Max: 51
76
71
 
77
72
  # Offense count: 4
78
73
  # Configuration parameters: CountKeywordArgs, MaxOptionalParameters.
79
74
  Metrics/ParameterLists:
80
- Max: 9
75
+ Max: 12
81
76
 
82
- # Offense count: 21
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: 7
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: 101
99
+ # Offense count: 109
104
100
  # Configuration parameters: CountAsOne.
105
101
  RSpec/ExampleLength:
106
- Max: 57
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: 88
128
+ # Offense count: 119
133
129
  RSpec/MultipleExpectations:
134
- Max: 11
130
+ Max: 14
135
131
 
136
- # Offense count: 17
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: 1
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
@@ -5,6 +5,7 @@ source "https://rubygems.org"
5
5
  # Specify your gem's dependencies in lutaml-model.gemspec
6
6
  gemspec
7
7
 
8
+ gem "bigdecimal"
8
9
  gem "equivalent-xml"
9
10
  gem "multi_json"
10
11
  gem "nokogiri"
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 the additional value types `DateTime` and `Hash`.
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, Lutaml::Model::Type::Integer
2123
- attribute :description, Lutaml::Model::Type::String
2307
+ attribute :length, :integer
2308
+ attribute :description, :string
2124
2309
  end
2125
2310
  ----
2126
2311
 
2127
2312
  [NOTE]
2128
2313
  ====
2129
- `Lutaml::Model` also supports specifying predefined value types as strings or
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, :integer
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 default
39
- return options[:default].call if options[:default].is_a?(Proc)
53
+ def raw?
54
+ @raw
55
+ end
40
56
 
41
- options[:default]
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?
@@ -0,0 +1,6 @@
1
+ module Lutaml
2
+ module Model
3
+ class IncorrectMappingArgumentsError < Error
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,9 @@
1
+ module Lutaml
2
+ module Model
3
+ class TypeNotEnabledError < Error
4
+ def initialize(type_name, value)
5
+ super("#{type_name} type is not enabled. Value: #{value}")
6
+ end
7
+ end
8
+ end
9
+ end
@@ -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"
@@ -6,8 +6,7 @@ module Lutaml
6
6
  module JsonAdapter
7
7
  class StandardJsonAdapter < JsonDocument
8
8
  def self.parse(json)
9
- attributes = JSON.parse(json, create_additions: false)
10
- new(attributes)
9
+ JSON.parse(json, create_additions: false)
11
10
  end
12
11
 
13
12
  def to_json(*args)
@@ -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