lutaml-model 0.8.0 → 0.8.2
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/.github/workflows/dependent-repos.json +9 -0
- data/.github/workflows/downstream-performance.yml +0 -3
- data/.rubocop_todo.yml +18 -186
- data/README.adoc +212 -15
- data/bench/bench_xmi.rb +6 -6
- data/bench/gate_config.rb +2 -9
- data/docs/_pages/configuration.adoc +155 -41
- data/docs/_pages/serialization_adapters.adoc +65 -14
- data/docs/index.adoc +3 -1
- data/docs/yamls_sequence.adoc +335 -0
- data/lib/lutaml/hash_format.rb +4 -0
- data/lib/lutaml/json/adapter/multi_json_adapter.rb +4 -2
- data/lib/lutaml/json/adapter/oj_adapter.rb +4 -2
- data/lib/lutaml/json.rb +4 -0
- data/lib/lutaml/key_value/adapter/json/multi_json_adapter.rb +4 -2
- data/lib/lutaml/key_value/adapter/json/oj_adapter.rb +4 -2
- data/lib/lutaml/model/adapter_resolver.rb +410 -0
- data/lib/lutaml/model/adapter_scope.rb +64 -0
- data/lib/lutaml/model/config.rb +84 -21
- data/lib/lutaml/model/configuration.rb +17 -249
- data/lib/lutaml/model/format_registry.rb +44 -117
- data/lib/lutaml/model/mapping/listener.rb +4 -2
- data/lib/lutaml/model/serialize/format_conversion.rb +42 -3
- data/lib/lutaml/model/serialize.rb +4 -2
- data/lib/lutaml/model/services/base.rb +4 -2
- data/lib/lutaml/model/version.rb +1 -1
- data/lib/lutaml/model.rb +2 -0
- data/lib/lutaml/toml.rb +10 -3
- data/lib/lutaml/xml/serialization/instance_methods.rb +6 -0
- data/lib/lutaml/xml.rb +3 -4
- data/lib/lutaml/yaml.rb +4 -0
- data/lib/lutaml/yamls/adapter/mapping.rb +7 -0
- data/lib/lutaml/yamls/adapter/standard_adapter.rb +23 -2
- data/lib/lutaml/yamls/adapter/transform.rb +105 -7
- data/lib/lutaml/yamls/adapter/yamls_sequence.rb +20 -0
- data/lib/lutaml/yamls/adapter/yamls_sequence_rule.rb +48 -0
- data/lib/lutaml/yamls/adapter.rb +2 -0
- data/spec/fixtures/geolexica_v2_concept.rb +136 -0
- data/spec/fixtures/geolexica_v2_sample.yaml +36 -0
- data/spec/fixtures/geolexica_v2_sample2.yaml +38 -0
- data/spec/fixtures/yamls_range_concept.rb +139 -0
- data/spec/lutaml/model/xml_decoupling_spec.rb +5 -4
- data/spec/lutaml/model/yamls_range_spec.rb +393 -0
- data/spec/lutaml/model/yamls_sequence_spec.rb +245 -0
- data/spec/spec_helper.rb +5 -0
- metadata +13 -3
- data/bench/bench_uniword.rb +0 -69
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
= YAMLS Sequence -- Heterogeneous YAML Stream Support
|
|
2
|
+
:toc:
|
|
3
|
+
:toclevels: 3
|
|
4
|
+
|
|
5
|
+
== Overview
|
|
6
|
+
|
|
7
|
+
A **YAML Stream** (file extension `.yaml`, format symbol `:yamls`) is a
|
|
8
|
+
multi-document YAML file where documents are separated by `---`. The
|
|
9
|
+
*YAMLS Sequence* feature allows different documents in the stream to map to
|
|
10
|
+
*different* model types at specific positions -- analogous to XML Schema's
|
|
11
|
+
`<sequence>` element.
|
|
12
|
+
|
|
13
|
+
== The Problem
|
|
14
|
+
|
|
15
|
+
Many real-world YAML streams contain heterogeneous document types:
|
|
16
|
+
|
|
17
|
+
[source,yaml]
|
|
18
|
+
----
|
|
19
|
+
--- # Doc 0 → ConceptIndex
|
|
20
|
+
data:
|
|
21
|
+
identifier: 3.5.8.8
|
|
22
|
+
localized_concepts:
|
|
23
|
+
eng: fbe1444a-7c11-555e-bb1b-680a4e6f2502
|
|
24
|
+
id: 0171b198-d068-53d9-8741-fb87e6755d62
|
|
25
|
+
|
|
26
|
+
--- # Doc 1 → LocalizedConcept
|
|
27
|
+
data:
|
|
28
|
+
definition:
|
|
29
|
+
- content: characteristic of a financial model
|
|
30
|
+
terms:
|
|
31
|
+
- type: expression
|
|
32
|
+
designation: membership-based
|
|
33
|
+
language_code: eng
|
|
34
|
+
id: fbe1444a-7c11-555e-bb1b-680a4e6f2502
|
|
35
|
+
----
|
|
36
|
+
|
|
37
|
+
Doc 0 is a `ConceptIndex`, docs 1+ are `LocalizedConcept` entries. The
|
|
38
|
+
existing `yamls` format with `map_instances` only supports *homogeneous*
|
|
39
|
+
streams where all documents share the same type.
|
|
40
|
+
|
|
41
|
+
== The Solution
|
|
42
|
+
|
|
43
|
+
The `sequence` block inside the `yamls` mapping DSL provides position-based
|
|
44
|
+
document mapping:
|
|
45
|
+
|
|
46
|
+
[source,ruby]
|
|
47
|
+
----
|
|
48
|
+
class ManagedConcept < Lutaml::Model::Serializable
|
|
49
|
+
attribute :index, ConceptIndex
|
|
50
|
+
attribute :localized, LocalizedConcept, collection: true
|
|
51
|
+
|
|
52
|
+
yamls do
|
|
53
|
+
sequence do
|
|
54
|
+
map_document 0, to: :index, type: ConceptIndex
|
|
55
|
+
map_document 1.., to: :localized, type: LocalizedConcept, collection: true
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
----
|
|
60
|
+
|
|
61
|
+
=== `map_document` Parameters
|
|
62
|
+
|
|
63
|
+
|===
|
|
64
|
+
| Parameter | Type | Description
|
|
65
|
+
|
|
66
|
+
| `position`
|
|
67
|
+
| Integer or Range
|
|
68
|
+
| Document position in the stream. See <<position-semantics>>.
|
|
69
|
+
|
|
70
|
+
| `to`
|
|
71
|
+
| Symbol
|
|
72
|
+
| Attribute name on the parent model.
|
|
73
|
+
|
|
74
|
+
| `type`
|
|
75
|
+
| Class
|
|
76
|
+
| Model class for deserialization of matching documents.
|
|
77
|
+
|
|
78
|
+
| `collection`
|
|
79
|
+
| Boolean (default: `false`)
|
|
80
|
+
| Set to `true` if multiple documents map to this attribute.
|
|
81
|
+
|===
|
|
82
|
+
|
|
83
|
+
[[position-semantics]]
|
|
84
|
+
== Position Semantics
|
|
85
|
+
|
|
86
|
+
The `position` parameter supports Integer, positive Range, negative indices,
|
|
87
|
+
and mixed Range expressions:
|
|
88
|
+
|
|
89
|
+
[cols="1,4"]
|
|
90
|
+
|===
|
|
91
|
+
| Position | Meaning
|
|
92
|
+
|
|
93
|
+
| `0` (Integer)
|
|
94
|
+
| Document at index 0 only. Singular (`collection: false`).
|
|
95
|
+
|
|
96
|
+
| `-1` (negative Integer)
|
|
97
|
+
| Last document in the stream.
|
|
98
|
+
|
|
99
|
+
| `-2` (negative Integer)
|
|
100
|
+
| Second-to-last document.
|
|
101
|
+
|
|
102
|
+
| `1..` (open Range)
|
|
103
|
+
| All documents from index 1 to the end. Collection (`collection: true`).
|
|
104
|
+
|
|
105
|
+
| `0..1` (bounded Range)
|
|
106
|
+
| Documents at indices 0 and 1. Collection.
|
|
107
|
+
|
|
108
|
+
| `2..4` (bounded Range)
|
|
109
|
+
| Documents at indices 2, 3, 4. Collection.
|
|
110
|
+
|
|
111
|
+
| `-2..-1` (negative Range)
|
|
112
|
+
| Last 2 documents in the stream. Collection.
|
|
113
|
+
|
|
114
|
+
| `1..-1` (mixed Range)
|
|
115
|
+
| Documents from index 1 to the end. Collection.
|
|
116
|
+
|
|
117
|
+
| `2..-1` (mixed Range)
|
|
118
|
+
| Documents from index 2 to the end. Collection.
|
|
119
|
+
|===
|
|
120
|
+
|
|
121
|
+
=== Negative Index Resolution
|
|
122
|
+
|
|
123
|
+
Negative indices are resolved relative to the total document count:
|
|
124
|
+
|
|
125
|
+
- `-1` resolves to `doc_count - 1` (last document)
|
|
126
|
+
- `-2` resolves to `doc_count - 2` (second-to-last)
|
|
127
|
+
- `-2..-1` resolves to `(doc_count - 2)..(doc_count - 1)` (last 2 documents)
|
|
128
|
+
|
|
129
|
+
Out-of-bounds indices are clamped: `-10..-1` on a 5-document stream resolves
|
|
130
|
+
to `0..4` (all documents).
|
|
131
|
+
|
|
132
|
+
== Examples
|
|
133
|
+
|
|
134
|
+
=== Two-Model Stream (Index + Localized Concepts)
|
|
135
|
+
|
|
136
|
+
[source,ruby]
|
|
137
|
+
----
|
|
138
|
+
class ManagedConcept < Lutaml::Model::Serializable
|
|
139
|
+
attribute :index, ConceptIndex
|
|
140
|
+
attribute :localized, LocalizedConcept, collection: true
|
|
141
|
+
|
|
142
|
+
yamls do
|
|
143
|
+
sequence do
|
|
144
|
+
map_document 0, to: :index, type: ConceptIndex
|
|
145
|
+
map_document 1.., to: :localized, type: LocalizedConcept, collection: true
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
managed = ManagedConcept.from_yamls(yaml_stream)
|
|
151
|
+
managed.index.data.identifier #=> "3.5.8.8"
|
|
152
|
+
managed.localized.first.data.language_code #=> "eng"
|
|
153
|
+
----
|
|
154
|
+
|
|
155
|
+
=== Three-Model Stream with Bounded Ranges
|
|
156
|
+
|
|
157
|
+
[source,ruby]
|
|
158
|
+
----
|
|
159
|
+
class Document < Lutaml::Model::Serializable
|
|
160
|
+
attribute :headers, Header, collection: true
|
|
161
|
+
attribute :entries, Entry, collection: true
|
|
162
|
+
attribute :footer, Footer
|
|
163
|
+
|
|
164
|
+
yamls do
|
|
165
|
+
sequence do
|
|
166
|
+
map_document 0..1, to: :headers, type: Header, collection: true
|
|
167
|
+
map_document 2..3, to: :entries, type: Entry, collection: true
|
|
168
|
+
map_document -1, to: :footer, type: Footer
|
|
169
|
+
end
|
|
170
|
+
end
|
|
171
|
+
end
|
|
172
|
+
----
|
|
173
|
+
|
|
174
|
+
=== Negative Ranges for Fixed-From-End Positioning
|
|
175
|
+
|
|
176
|
+
Useful when the front of the stream varies but the tail structure is fixed:
|
|
177
|
+
|
|
178
|
+
[source,ruby]
|
|
179
|
+
----
|
|
180
|
+
class Report < Lutaml::Model::Serializable
|
|
181
|
+
attribute :headers, Header, collection: true
|
|
182
|
+
attribute :trailers, Entry, collection: true
|
|
183
|
+
|
|
184
|
+
yamls do
|
|
185
|
+
sequence do
|
|
186
|
+
map_document 0..1, to: :headers, type: Header, collection: true
|
|
187
|
+
map_document -2..-1, to: :trailers, type: Entry, collection: true
|
|
188
|
+
end
|
|
189
|
+
end
|
|
190
|
+
end
|
|
191
|
+
----
|
|
192
|
+
|
|
193
|
+
=== Mixed Ranges (Single + Range + Negative)
|
|
194
|
+
|
|
195
|
+
Three different types across a 7-document stream:
|
|
196
|
+
|
|
197
|
+
[source,ruby]
|
|
198
|
+
----
|
|
199
|
+
class ThreeRanges < Lutaml::Model::Serializable
|
|
200
|
+
attribute :headers, Header, collection: true
|
|
201
|
+
attribute :entries, Entry, collection: true
|
|
202
|
+
attribute :footer, Footer
|
|
203
|
+
|
|
204
|
+
yamls do
|
|
205
|
+
sequence do
|
|
206
|
+
map_document 0..1, to: :headers, type: Header, collection: true
|
|
207
|
+
map_document -3..-2, to: :entries, type: Entry, collection: true
|
|
208
|
+
map_document -1, to: :footer, type: Footer
|
|
209
|
+
end
|
|
210
|
+
end
|
|
211
|
+
end
|
|
212
|
+
----
|
|
213
|
+
|
|
214
|
+
== Serialization (Round-Trip)
|
|
215
|
+
|
|
216
|
+
Calling `to_yamls` on a model with a sequence definition produces a valid
|
|
217
|
+
YAML stream. Each rule's values are serialized in rule order:
|
|
218
|
+
|
|
219
|
+
[source,ruby]
|
|
220
|
+
----
|
|
221
|
+
managed = ManagedConcept.from_yamls(yaml_stream)
|
|
222
|
+
output = managed.to_yamls
|
|
223
|
+
managed2 = ManagedConcept.from_yamls(output)
|
|
224
|
+
|
|
225
|
+
managed2.index.id == managed.index.id # true
|
|
226
|
+
managed2.localized.first.id == managed.localized.first.id # true
|
|
227
|
+
----
|
|
228
|
+
|
|
229
|
+
== Loading a Directory of Sequence-Based Files
|
|
230
|
+
|
|
231
|
+
Each file is a complete YAML stream (one model instance). Load them
|
|
232
|
+
individually and assemble into a collection:
|
|
233
|
+
|
|
234
|
+
[source,ruby]
|
|
235
|
+
----
|
|
236
|
+
concepts = Dir["glossary/*.yaml"].map do |f|
|
|
237
|
+
ManagedConcept.from_yamls(File.read(f))
|
|
238
|
+
end
|
|
239
|
+
collection = ManagedConceptCollection.new(concepts)
|
|
240
|
+
----
|
|
241
|
+
|
|
242
|
+
== Architecture
|
|
243
|
+
|
|
244
|
+
=== New Classes
|
|
245
|
+
|
|
246
|
+
|===
|
|
247
|
+
| Class | Responsibility
|
|
248
|
+
|
|
249
|
+
| `Lutaml::Yamls::Adapter::YamlsSequence`
|
|
250
|
+
| Ordered collection of sequence rules
|
|
251
|
+
|
|
252
|
+
| `Lutaml::Yamls::Adapter::YamlsSequenceRule`
|
|
253
|
+
| Maps doc position to model type, handles value assignment
|
|
254
|
+
|
|
255
|
+
| `Lutaml::Yamls::Adapter::Mapping`
|
|
256
|
+
| DSL surface (`sequence {}` block)
|
|
257
|
+
|
|
258
|
+
| `Lutaml::Yamls::Adapter::Transform`
|
|
259
|
+
| Sequence-aware deserialization/serialization
|
|
260
|
+
|===
|
|
261
|
+
|
|
262
|
+
=== Flow
|
|
263
|
+
|
|
264
|
+
.Deserialization
|
|
265
|
+
[source]
|
|
266
|
+
----
|
|
267
|
+
YAML Stream String
|
|
268
|
+
│
|
|
269
|
+
▼ StandardAdapter.parse (YAML.load_stream)
|
|
270
|
+
Array<Hash> (one per document)
|
|
271
|
+
│
|
|
272
|
+
▼ Transform.data_to_model_with_sequence
|
|
273
|
+
│ for each YamlsSequenceRule:
|
|
274
|
+
│ extract docs for position (Integer or Range)
|
|
275
|
+
│ deserialize each doc via YAML transformer
|
|
276
|
+
│ assign to model attribute
|
|
277
|
+
▼
|
|
278
|
+
Model Instance
|
|
279
|
+
----
|
|
280
|
+
|
|
281
|
+
.Serialization
|
|
282
|
+
[source]
|
|
283
|
+
----
|
|
284
|
+
Model Instance
|
|
285
|
+
│
|
|
286
|
+
▼ Transform.model_to_data_with_sequence
|
|
287
|
+
│ for each YamlsSequenceRule:
|
|
288
|
+
│ read attribute value from instance
|
|
289
|
+
│ serialize each item via YAML transformer
|
|
290
|
+
│ collect into ordered array
|
|
291
|
+
▼
|
|
292
|
+
Array<Hash>
|
|
293
|
+
│
|
|
294
|
+
▼ StandardAdapter.to_yamls (YAML.dump per doc)
|
|
295
|
+
YAML Stream String
|
|
296
|
+
----
|
|
297
|
+
|
|
298
|
+
== Files
|
|
299
|
+
|
|
300
|
+
|===
|
|
301
|
+
| File | Description
|
|
302
|
+
|
|
303
|
+
| `lib/lutaml/yamls/adapter.rb`
|
|
304
|
+
| Autoloads new classes
|
|
305
|
+
|
|
306
|
+
| `lib/lutaml/yamls/adapter/yamls_sequence.rb`
|
|
307
|
+
| `YamlsSequence` class
|
|
308
|
+
|
|
309
|
+
| `lib/lutaml/yamls/adapter/yamls_sequence_rule.rb`
|
|
310
|
+
| `YamlsSequenceRule` class with `resolve_range`
|
|
311
|
+
|
|
312
|
+
| `lib/lutaml/yamls/adapter/mapping.rb`
|
|
313
|
+
| `Mapping` with `sequence` DSL
|
|
314
|
+
|
|
315
|
+
| `lib/lutaml/yamls/adapter/transform.rb`
|
|
316
|
+
| Sequence-aware de/serialization
|
|
317
|
+
|
|
318
|
+
| `lib/lutaml/yamls/adapter/standard_adapter.rb`
|
|
319
|
+
| `YAML.load_stream` based parser
|
|
320
|
+
|
|
321
|
+
| `lib/lutaml/model/serialize/format_conversion.rb`
|
|
322
|
+
| `array_passthrough_format?` hook
|
|
323
|
+
|
|
324
|
+
| `spec/lutaml/model/yamls_sequence_spec.rb`
|
|
325
|
+
| Geolexica v2 integration tests
|
|
326
|
+
|
|
327
|
+
| `spec/lutaml/model/yamls_range_spec.rb`
|
|
328
|
+
| Range position tests (negative, bounded, mixed)
|
|
329
|
+
|
|
330
|
+
| `spec/fixtures/geolexica_v2_concept.rb`
|
|
331
|
+
| Geolexica v2 model fixture
|
|
332
|
+
|
|
333
|
+
| `spec/fixtures/yamls_range_concept.rb`
|
|
334
|
+
| Range test model fixture
|
|
335
|
+
|===
|
data/lib/lutaml/hash_format.rb
CHANGED
|
@@ -18,6 +18,10 @@ Lutaml::Model::FormatRegistry.register(
|
|
|
18
18
|
adapter_class: Lutaml::HashFormat::Adapter::StandardAdapter,
|
|
19
19
|
transformer: Lutaml::HashFormat::Adapter::Transform,
|
|
20
20
|
key_value: true,
|
|
21
|
+
adapter_options: {
|
|
22
|
+
available: %i[standard standard_hash],
|
|
23
|
+
default: :standard,
|
|
24
|
+
},
|
|
21
25
|
)
|
|
22
26
|
|
|
23
27
|
# Register Hash type serializers
|
|
@@ -16,7 +16,8 @@ module Lutaml
|
|
|
16
16
|
"multi_json gem is not available. Please add 'multi_json' to your Gemfile."
|
|
17
17
|
end
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
# rubocop:disable Style/ArgumentsForwarding -- anonymous * requires Ruby 3.2+
|
|
20
|
+
def to_json(*args)
|
|
20
21
|
require "multi_json"
|
|
21
22
|
# Handle KeyValueElement input (new symmetric architecture)
|
|
22
23
|
attributes_to_serialize = if @attributes.is_a?(Lutaml::KeyValue::DataModel::Element)
|
|
@@ -27,7 +28,8 @@ module Lutaml
|
|
|
27
28
|
@attributes
|
|
28
29
|
end
|
|
29
30
|
|
|
30
|
-
MultiJson.dump(attributes_to_serialize, *)
|
|
31
|
+
MultiJson.dump(attributes_to_serialize, *args)
|
|
32
|
+
# rubocop:enable Style/ArgumentsForwarding
|
|
31
33
|
rescue LoadError
|
|
32
34
|
raise LoadError,
|
|
33
35
|
"multi_json gem is not available. Please add 'multi_json' to your Gemfile."
|
|
@@ -16,7 +16,8 @@ module Lutaml
|
|
|
16
16
|
"oj gem is not available. Please add 'oj' to your Gemfile or use the StandardAdapter."
|
|
17
17
|
end
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
# rubocop:disable Style/ArgumentsForwarding -- anonymous * requires Ruby 3.2+
|
|
20
|
+
def to_json(*args)
|
|
20
21
|
require "oj"
|
|
21
22
|
# Handle KeyValueElement input (new symmetric architecture)
|
|
22
23
|
attributes_to_serialize = if @attributes.is_a?(Lutaml::KeyValue::DataModel::Element)
|
|
@@ -27,7 +28,8 @@ module Lutaml
|
|
|
27
28
|
@attributes
|
|
28
29
|
end
|
|
29
30
|
|
|
30
|
-
Oj.dump(attributes_to_serialize, *)
|
|
31
|
+
Oj.dump(attributes_to_serialize, *args)
|
|
32
|
+
# rubocop:enable Style/ArgumentsForwarding
|
|
31
33
|
rescue LoadError
|
|
32
34
|
raise LoadError,
|
|
33
35
|
"oj gem is not available. Please add 'oj' to your Gemfile or use the StandardAdapter."
|
data/lib/lutaml/json.rb
CHANGED
|
@@ -51,6 +51,10 @@ Lutaml::Model::FormatRegistry.register(
|
|
|
51
51
|
adapter_class: Lutaml::Json::Adapter::StandardAdapter,
|
|
52
52
|
transformer: Lutaml::Json::Adapter::Transform,
|
|
53
53
|
key_value: true,
|
|
54
|
+
adapter_options: {
|
|
55
|
+
available: %i[standard standard_json multi_json oj],
|
|
56
|
+
default: :standard,
|
|
57
|
+
},
|
|
54
58
|
)
|
|
55
59
|
|
|
56
60
|
# Register JSON type serializers
|
|
@@ -20,7 +20,8 @@ module Lutaml
|
|
|
20
20
|
"multi_json gem is not available. Please add 'multi_json' to your Gemfile."
|
|
21
21
|
end
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
# rubocop:disable Style/ArgumentsForwarding -- anonymous * requires Ruby 3.2+
|
|
24
|
+
def to_json(*args)
|
|
24
25
|
require "multi_json"
|
|
25
26
|
# Handle KeyValueElement input (new symmetric architecture)
|
|
26
27
|
attributes_to_serialize = if @attributes.is_a?(Lutaml::KeyValue::DataModel::Element)
|
|
@@ -31,7 +32,8 @@ module Lutaml
|
|
|
31
32
|
@attributes
|
|
32
33
|
end
|
|
33
34
|
|
|
34
|
-
MultiJson.dump(attributes_to_serialize, *)
|
|
35
|
+
MultiJson.dump(attributes_to_serialize, *args)
|
|
36
|
+
# rubocop:enable Style/ArgumentsForwarding
|
|
35
37
|
rescue LoadError
|
|
36
38
|
raise LoadError,
|
|
37
39
|
"multi_json gem is not available. Please add 'multi_json' to your Gemfile."
|
|
@@ -20,7 +20,8 @@ module Lutaml
|
|
|
20
20
|
"oj gem is not available. Please add 'oj' to your Gemfile or use the StandardAdapter."
|
|
21
21
|
end
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
# rubocop:disable Style/ArgumentsForwarding -- anonymous * requires Ruby 3.2+
|
|
24
|
+
def to_json(*args)
|
|
24
25
|
require "oj"
|
|
25
26
|
# Handle KeyValueElement input (new symmetric architecture)
|
|
26
27
|
attributes_to_serialize = if @attributes.is_a?(Lutaml::KeyValue::DataModel::Element)
|
|
@@ -31,7 +32,8 @@ module Lutaml
|
|
|
31
32
|
@attributes
|
|
32
33
|
end
|
|
33
34
|
|
|
34
|
-
Oj.dump(attributes_to_serialize, *)
|
|
35
|
+
Oj.dump(attributes_to_serialize, *args)
|
|
36
|
+
# rubocop:enable Style/ArgumentsForwarding
|
|
35
37
|
rescue LoadError
|
|
36
38
|
raise LoadError,
|
|
37
39
|
"oj gem is not available. Please add 'oj' to your Gemfile or use the StandardAdapter."
|