1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
//! **ITS-XML** — canonical XML serialization (openEHR ITS-XML).
//!
//! A document is written in either of
//! the two published wire lineages: `http://schemas.openehr.org/v1`
//! (Release-1.0.2v2, the STABLE bundle) and `http://schemas.openehr.org/v2`
//! (Release-2.0.0v2, TRIAL upstream). One generated impl set serves both: the
//! documents it writes differ only by the root `xmlns`, selected at serialize
//! time. The two vendored SCHEMA bundles are not equivalent, though — the v1
//! bundle is frozen at an older RM generation (`schemas/xml/PROVENANCE.md`
//! §"Two lineages"), so a served v1 document can carry RM 1.2.0 members its
//! own schema predates.
//!
//! The `ToXml`/`FromXml` impls for the RM/BASE spec types are **generated** by
//! `openehr-codegen`'s `emit-xml` target into `generated`, driven by
//! the vendored XSDs (`schemas/xml/`) + the BMM field model. This module is the
//! hand-written [`runtime`] (traits + `quick-xml` writer/reader) and the public
//! entry points. Regenerate with `cargo run -p openehr-codegen -- emit-xml`.
// Trait impls for the spec types — compiled for their effect; nothing to export.
pub use ;
/// One published ITS-XML **document element** (a global `xs:element` of the
/// vendored bundles) that this codec serves as a canonical-XML root.
/// The published document elements served as canonical-XML roots.
///
/// This is the ONE statement of the published-element fact both the REST layer
/// and the admin archive consume (the schemas live in this crate:
/// `schemas/xml/`). Both published lineages spell every entry identically:
///
/// - `<xs:element name="composition" type="COMPOSITION"/>` —
/// `its-xml-1.0.2-nsv1/ALL/Composition.xsd`;
/// `its-xml-2.0.0-nsv2/RM/latest/documents/Composition.xsd`.
/// - `<xs:element name="version" type="VERSION"/>` over
/// `<xs:complexType name="VERSION" abstract="true">` —
/// `…/ALL/Version.xsd`; `…/RM/latest/documents/Version.xsd`.
/// - `<xs:element name="items" type="LOCATABLE"/>` over
/// `<xs:complexType name="LOCATABLE" abstract="true">` —
/// `…/ALL/Structure.xsd`; `…/RM/latest/documents/Structure.xsd`.
///
/// A root name the schemas publish no element for is deliberately absent —
/// the ITS-REST §XML Format MUST ("responses MUST conform to the [published
/// XSDs]") has nothing to bind to there (register AMB-167).
pub const PUBLISHED_ROOTS: & = &;
/// The declared **abstract** XSD type of published root `element`, when its
/// type is abstract (the instance must then carry `xsi:type` — see
/// [`PublishedRoot::type_is_abstract`]).
///
/// `None` for a concretely-typed root and for a name the schemas publish no
/// element for.
/// Serialize an RM value to canonical openEHR XML in the **default** wire
/// lineage, namespace `http://schemas.openehr.org/v1`. `root_tag` is the root
/// element name (e.g. `"composition"`).
///
/// NOTE: this LIBRARY default is the RELEASED-STABLE ITS-XML lineage (the
/// upstream repository README marks the 2.0.0 schemas *TRIAL* and directs
/// stable consumers to `Release-1.0.2` —
/// `docs/specs/openehr/ITS-XML/README.adoc` §"Releases and IM Versions").
/// The REST layer chooses its lineage explicitly per request via
/// [`to_canonical_xml_ns`] and SERVES v2 by default (owner ruling 2026-08-03,
/// #1666: the v1 bundle cannot describe the RM 1.2.0 the server emits —
/// register AMB-185); this function is the fixed-lineage convenience for
/// gates and tools, not the wire default.
///
/// # Errors
/// Propagates serialization errors.
Sized>
/// Serialize an RM value to canonical openEHR XML in an explicitly chosen wire
/// lineage — the namespace-parameterized sibling of [`to_canonical_xml`].
///
/// Both lineages are vendored and validated (`schemas/xml/`), and the
/// generated codec is shared: `ns` selects only the root `xmlns` the document
/// declares (`runtime::Namespace`). Callers that have no reason to choose stay
/// on [`to_canonical_xml`].
///
/// NOTE: OPT 1.4 operational templates are NOT served through here — they are
/// AM documents with their own `<template>` root and are always emitted in the
/// v1 lineage (`crate::opt14::to_xml`), never negotiated: the lineage split
/// documented in `docs/specs/openehr/ITS-XML/README.adoc` §"Releases and IM
/// Versions" keeps `Release-1.0.2` the STABLE bundle, and an operational
/// template is not an RM canonical document a client reads back in a chosen
/// representation.
///
/// # Errors
/// Propagates serialization errors.
Sized>
/// Serialize an RM value under a root element whose **XSD-declared type is
/// abstract**, so the instance must name its concrete type — the
/// declared-type-aware sibling of [`to_canonical_xml_ns`].
///
/// [`to_canonical_xml`] passes no declared type at the root, so its root
/// element never carries `xsi:type`. That is right for a published global
/// element whose type is concrete (`<composition>`, `<ehr_status>`, …) and
/// WRONG for one whose type is abstract: `ALL/Version.xsd` publishes
/// `<xs:element name="version" type="VERSION"/>` over
/// `<xs:complexType name="VERSION" abstract="true">`, and XML Schema Part 1
/// forbids an element instance from using an abstract type directly — the
/// instance must select a non-abstract derived type with `xsi:type`
/// (<https://www.w3.org/TR/xmlschema-1/#xsi_type>, §2.6.1 + §3.4.6). Passing
/// `declared_type = "VERSION"` here makes an `ORIGINAL_VERSION` emit
/// `xsi:type="ORIGINAL_VERSION"` through the very same polymorphic-dispatch
/// mechanism every nested slot uses, so the document validates against the
/// published schema.
///
/// # Errors
/// Propagates serialization errors.
Sized>
/// Deserialize an RM value from a canonical openEHR XML document.
///
/// Reading is namespace-agnostic by construction: the reader dispatches on
/// local element names and `xsi:type`, and never inspects the document's root
/// `xmlns`. Both published lineages therefore parse identically. The 2.0.0
/// restructure changed the namespace the schemas declare
/// (`docs/specs/openehr/ITS-XML/README.adoc` §"Releases and IM Versions":
/// "Simultaneously, the internal namespace used in the schemas is also changed
/// to `http://schemas.openehr.org/v2`") — it did NOT make the two bundles
/// interchangeable: the flat `Release-1.0.2v2` bundle is frozen at an older RM
/// generation and declares neither `FOLDER.details` nor 22 other RM 1.2.0
/// attributes, nor 50 RM 1.2.0 classes at all
/// (`schemas/xml/PROVENANCE.md` §"Two lineages"). Namespace-agnostic READING
/// stays sound regardless, because every element name and `xsi:type` the
/// reader dispatches on is spelled identically in both lineages; only what the
/// two schemas ACCEPT differs.
///
/// # Errors
/// Propagates parse errors.