lutaml-model 0.8.98 → 0.8.99
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/docs/_guides/gem-integration.adoc +85 -0
- data/docs/_guides/index.adoc +6 -1
- data/docs/_guides/type-registers-contexts.adoc +126 -0
- data/lib/lutaml/model/version.rb +1 -1
- metadata +3 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 41d8d37a85f86f8d8f30d632c36526fe311ba0156f01a096a15717627f29ec72
|
|
4
|
+
data.tar.gz: f15221cd4017756a1045502f77b588df6ae8f3e62ff39b38ac10c8d6f4a68115
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 509fc9f6462f37013113fdcb7a582ca70e9ce0ff021b51c780f9afdd66c03ec2c62213bd0c76a680dc993db138182b7260ed821757b37946b2b61941e2b9b066
|
|
7
|
+
data.tar.gz: e01bb47f5085c77f6ce840f31ac4f9f243271846267f1083c2c099cfae7f2ced2979f73a61a3a44ea0b0d609b9176a6e8d64e8841994c794382fd0a16c0880f2
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Integrating lutaml-model in a Gem
|
|
3
|
+
nav_order: 21
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
= Integrating lutaml-model in a gem
|
|
7
|
+
|
|
8
|
+
For gem authors, the integration contract is simple: **depend on
|
|
9
|
+
`lutaml-model` and nothing else format-specific.** Every XML, YAML,
|
|
10
|
+
JSON, and TOML engine is resolved at runtime, and the standard
|
|
11
|
+
adapters (Nokogiri through moxml, Psych, the `json` gem, toml-rb
|
|
12
|
+
compatible engines) cover a working default everywhere.
|
|
13
|
+
|
|
14
|
+
== Declaring the dependency
|
|
15
|
+
|
|
16
|
+
[source,ruby]
|
|
17
|
+
----
|
|
18
|
+
spec.add_dependency "lutaml-model", "~> 0.8"
|
|
19
|
+
----
|
|
20
|
+
|
|
21
|
+
Do not add Nokogiri, Ox, Oga, leptris, yeptris, or teptris to your
|
|
22
|
+
gemspec. All engines are optional at runtime:
|
|
23
|
+
|
|
24
|
+
* when an engine gem is in the end user's bundle, the matching
|
|
25
|
+
adapters prefer it (see the
|
|
26
|
+
link:../native-engines[native engines guide]);
|
|
27
|
+
* when it is not, adapters fall back to the standard engine for
|
|
28
|
+
that format — parsing and generation semantics are identical,
|
|
29
|
+
error classes are re-raised as their standard-library equivalents.
|
|
30
|
+
|
|
31
|
+
There is no code path to write, no require order to respect, and no
|
|
32
|
+
capability probe to perform in your gem.
|
|
33
|
+
|
|
34
|
+
== Testing across adapters
|
|
35
|
+
|
|
36
|
+
Your test suite should exercise the adapters your users may run.
|
|
37
|
+
Lutaml::Model's own suite parameterizes the XML adapter through an
|
|
38
|
+
environment variable; the same shape works downstream:
|
|
39
|
+
|
|
40
|
+
[source,ruby]
|
|
41
|
+
----
|
|
42
|
+
ADAPTER = ENV.fetch("XML_ADAPTER", "nokogiri").to_sym
|
|
43
|
+
|
|
44
|
+
RSpec.configure do |config|
|
|
45
|
+
config.before(:suite) do
|
|
46
|
+
Lutaml::Model::Config.xml_adapter_type = ADAPTER
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
----
|
|
50
|
+
|
|
51
|
+
Run the matrix in CI — one leg per adapter the standard runners can
|
|
52
|
+
install:
|
|
53
|
+
|
|
54
|
+
[source,sh]
|
|
55
|
+
----
|
|
56
|
+
XML_ADAPTER=nokogiri bundle exec rspec
|
|
57
|
+
XML_ADAPTER=ox bundle exec rspec
|
|
58
|
+
XML_ADAPTER=leptris bundle exec rspec # requires the leptris gem in that leg's bundle
|
|
59
|
+
----
|
|
60
|
+
|
|
61
|
+
Engine gems belong in the CI *Gemfile* (a `group :test` entry or a
|
|
62
|
+
separate CI gemfile), never in the gemspec. Start with the primary
|
|
63
|
+
adapter (Nokogiri) and enable further legs incrementally as they
|
|
64
|
+
pass — the same "adapter-first" strategy this library's own suite
|
|
65
|
+
uses.
|
|
66
|
+
|
|
67
|
+
== Semantics your users can rely on
|
|
68
|
+
|
|
69
|
+
* Adapter choice never changes results: the plan fast path and the
|
|
70
|
+
interpretive pipeline produce identical output; on engines below
|
|
71
|
+
a capability floor the affected models parse interpretively
|
|
72
|
+
rather than degrade (see the version-floor note in the
|
|
73
|
+
link:../native-engines[native engines guide]).
|
|
74
|
+
* Parse failures raise the standard error classes wrapped as
|
|
75
|
+
`Lutaml::Model::InvalidFormatError` on every engine — code that
|
|
76
|
+
rescues those classes works regardless of the bundle.
|
|
77
|
+
|
|
78
|
+
== Rules of thumb
|
|
79
|
+
|
|
80
|
+
* Gemspec: `lutaml-model` only. CI gemfiles: the engines you test.
|
|
81
|
+
* Expose format options you want to forward (pretty printing,
|
|
82
|
+
encoding) — never the adapter itself.
|
|
83
|
+
* If you ship models for multiple schema versions, see
|
|
84
|
+
link:../type-registers-contexts[type registers and contexts] for
|
|
85
|
+
per-version trees and substitution.
|
data/docs/_guides/index.adoc
CHANGED
|
@@ -28,8 +28,13 @@ Task-oriented guides for accomplishing specific goals with Lutaml::Model.
|
|
|
28
28
|
* link:../advanced-mapping[Advanced Attribute Mapping] - Same-name dispatch on attribute values (`when_attribute`), grouped declarations, custom methods, delegation
|
|
29
29
|
* link:../grammar-backed-formats[Grammar-Backed String Formats] - Register a grammar engine as a serialization format (identifier strings, DSLs)
|
|
30
30
|
|
|
31
|
-
==
|
|
31
|
+
== Model architecture and integration
|
|
32
|
+
|
|
33
|
+
* link:../type-registers-contexts[Type Registers and Contexts] - Multi-version class trees, derived contexts, and model substitution
|
|
34
|
+
* link:../gem-integration[Integrating lutaml-model in a Gem] - Dependency contract, adapter deferral, cross-adapter testing
|
|
32
35
|
|
|
36
|
+
== Performance
|
|
37
|
+
/
|
|
33
38
|
* link:../native-engines[Native engines (leptris / yeptris / teptris)] - Drop-in XML/YAML/JSON/TOML engine upgrades via bundle opt-in
|
|
34
39
|
|
|
35
40
|
== Linked Data serialization
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Type Registers and Contexts
|
|
3
|
+
nav_order: 20
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
= Type registers and contexts
|
|
7
|
+
|
|
8
|
+
Lutaml::Model resolves every attribute type — Symbol or class —
|
|
9
|
+
through a per-application *register*: a named table of types scoped
|
|
10
|
+
so that different class trees can share mapping definitions without
|
|
11
|
+
colliding. Registers are the mechanism behind multi-version model
|
|
12
|
+
suites and model substitution.
|
|
13
|
+
|
|
14
|
+
== Registers
|
|
15
|
+
|
|
16
|
+
A register maps type ids to classes. Classes declare the register
|
|
17
|
+
they belong to:
|
|
18
|
+
|
|
19
|
+
[source,ruby]
|
|
20
|
+
----
|
|
21
|
+
module MyModels
|
|
22
|
+
class Mi < Lutaml::Model::Serializable
|
|
23
|
+
def self.lutaml_default_register
|
|
24
|
+
:my_models
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
----
|
|
29
|
+
|
|
30
|
+
Symbol attribute types resolve in the declaring class's register,
|
|
31
|
+
so the same symbol can mean different classes per tree — the
|
|
32
|
+
multi-version pattern below builds on this.
|
|
33
|
+
|
|
34
|
+
== Contexts: derived registers with substitutions
|
|
35
|
+
|
|
36
|
+
A *context* is a derived type-resolution scope: it carries a
|
|
37
|
+
registry, fallback registers, and — the part that powers model
|
|
38
|
+
substitution — a list of type substitutions. Contexts are created
|
|
39
|
+
through the global registry:
|
|
40
|
+
|
|
41
|
+
[source,ruby]
|
|
42
|
+
----
|
|
43
|
+
Lutaml::Model::GlobalContext.create_context(
|
|
44
|
+
id: :custom_models,
|
|
45
|
+
fallback_to: [:my_models],
|
|
46
|
+
substitutions: [
|
|
47
|
+
{ from_type: MyModels::Mover, to_type: Overset },
|
|
48
|
+
],
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
instance = MyModels::Math.from_xml(xml, context: :custom_models)
|
|
52
|
+
instance.mover_value.first # => #<Overset>
|
|
53
|
+
----
|
|
54
|
+
|
|
55
|
+
Every attribute whose type resolves to `MyModels::Mover` — at any
|
|
56
|
+
depth of the tree — hydrates `Overset` in that context. Substitution
|
|
57
|
+
is type-based, so "swap this class everywhere it is referenced" and
|
|
58
|
+
"swap it only inside this one path" are the same operation scoped by
|
|
59
|
+
context: create two contexts with different substitution lists.
|
|
60
|
+
|
|
61
|
+
Contexts are cheap and disposable:
|
|
62
|
+
|
|
63
|
+
[source,ruby]
|
|
64
|
+
----
|
|
65
|
+
Lutaml::Model::GlobalContext.unregister_context(:custom_models)
|
|
66
|
+
----
|
|
67
|
+
|
|
68
|
+
=== The custom-models convenience
|
|
69
|
+
|
|
70
|
+
A whole-table convenience reads exactly like a class-swap hash and
|
|
71
|
+
derives the context for you:
|
|
72
|
+
|
|
73
|
+
[source,ruby]
|
|
74
|
+
----
|
|
75
|
+
models = { MyModels::Mover => Overset, MyModels::Mi => BoldMi }
|
|
76
|
+
Lutaml::Model::GlobalContext.create_context(
|
|
77
|
+
id: :custom, fallback_to: [:my_models],
|
|
78
|
+
substitutions: models.map { |from, to| { from_type: from, to_type: to } },
|
|
79
|
+
)
|
|
80
|
+
MyModels::Math.from_xml(xml, context: :custom)
|
|
81
|
+
----
|
|
82
|
+
|
|
83
|
+
Substitute classes should inherit from the class they replace (or
|
|
84
|
+
provide its full attribute surface) so mappings and serialization
|
|
85
|
+
keep working.
|
|
86
|
+
|
|
87
|
+
=== Substituting a symbol entry instead of a class
|
|
88
|
+
|
|
89
|
+
Registers accept direct class registrations under a type id — useful
|
|
90
|
+
when a tree declares `attribute :row, :row` and you want the symbol
|
|
91
|
+
to resolve to your own class within a derived register:
|
|
92
|
+
|
|
93
|
+
[source,ruby]
|
|
94
|
+
----
|
|
95
|
+
derived = Lutaml::Model::Register.new(:derived, fallback: [:my_models])
|
|
96
|
+
derived.register_model(NewRow, id: :row)
|
|
97
|
+
MyModels::Doc.from_xml(xml, register: derived)
|
|
98
|
+
----
|
|
99
|
+
|
|
100
|
+
(`register:` is the pre-context spelling; prefer `context:` with
|
|
101
|
+
substitutions in new code.)
|
|
102
|
+
|
|
103
|
+
== Multi-version class trees
|
|
104
|
+
|
|
105
|
+
The flagship pattern combines registers with per-version classes
|
|
106
|
+
and shared mapping modules:
|
|
107
|
+
|
|
108
|
+
* a `Base::Mrow` module holds the mapping DSL once;
|
|
109
|
+
* each version declares `class Mrow` mixing the module in and
|
|
110
|
+
pointing `lutaml_default_register` at its version's register;
|
|
111
|
+
* attributes use symbol types, so `attribute :mrow, :mrow` means
|
|
112
|
+
the right class per tree;
|
|
113
|
+
* a substitution context swaps individual classes for one call
|
|
114
|
+
without re-opening or redefining anything.
|
|
115
|
+
|
|
116
|
+
Nothing re-opens generated classes, and each version's tree stays
|
|
117
|
+
independent — no hidden delegation.
|
|
118
|
+
|
|
119
|
+
== Rules of thumb
|
|
120
|
+
|
|
121
|
+
* Prefer contexts over global configuration: substitutions scoped
|
|
122
|
+
to a context cannot leak into other resolutions.
|
|
123
|
+
* Substitute classes should inherit the original; substitution then
|
|
124
|
+
preserves every mapping declared on the base.
|
|
125
|
+
* Clean up exploratory contexts with `unregister_context` in test
|
|
126
|
+
teardowns — contexts are global state.
|
data/lib/lutaml/model/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: lutaml-model
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.8.
|
|
4
|
+
version: 0.8.99
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ribose Inc.
|
|
@@ -207,6 +207,7 @@ files:
|
|
|
207
207
|
- docs/_guides/creating-xsd.adoc
|
|
208
208
|
- docs/_guides/custom-methods.adoc
|
|
209
209
|
- docs/_guides/document-validation.adoc
|
|
210
|
+
- docs/_guides/gem-integration.adoc
|
|
210
211
|
- docs/_guides/grammar-backed-formats.adoc
|
|
211
212
|
- docs/_guides/index.adoc
|
|
212
213
|
- docs/_guides/jsonld-serialization.adoc
|
|
@@ -220,6 +221,7 @@ files:
|
|
|
220
221
|
- docs/_guides/schema-generation.adoc
|
|
221
222
|
- docs/_guides/schema-import.adoc
|
|
222
223
|
- docs/_guides/turtle-serialization.adoc
|
|
224
|
+
- docs/_guides/type-registers-contexts.adoc
|
|
223
225
|
- docs/_guides/value-transformations.adoc
|
|
224
226
|
- docs/_guides/xml-mapping.adoc
|
|
225
227
|
- docs/_guides/xml-mappings-guide.adoc
|