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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e9f7cb26a9f87fbfe0feb461b25dd3e8b50e32d64bbbd32b23f848e96355965b
4
- data.tar.gz: 1961e58a64424ca1d69181f3e873d107e8f1d8762f1d1155c1de953c883ceaa1
3
+ metadata.gz: 41d8d37a85f86f8d8f30d632c36526fe311ba0156f01a096a15717627f29ec72
4
+ data.tar.gz: f15221cd4017756a1045502f77b588df6ae8f3e62ff39b38ac10c8d6f4a68115
5
5
  SHA512:
6
- metadata.gz: 8624d39f5b4d556f6c72e7f76fa6ab262490a1583d5776756373dd4ea220bb1ba89e3f57f7774efa8f5f8c16f631f312ac149ed93ed651c15223068265bea629
7
- data.tar.gz: 1249cac19b6f80880f5eb0c29cb0b2df17ff5813021573f6c2b63c923f6b2d63d2f579b9d14ebf18b8dae774df208787cef61cbfc507848fd99afffbc28b1404
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.
@@ -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
- == Performance
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.
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Lutaml
4
4
  module Model
5
- VERSION = "0.8.98"
5
+ VERSION = "0.8.99"
6
6
  end
7
7
  end
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.98
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