Skip to main content

fhir_types/r4/
primitives.rs

1// @generated by fhir-codegen from hl7.fhir.r4.core 4.0.1. DO NOT EDIT.
2// Change the emitter (tools/fhir-codegen) and regenerate.
3// SPDX-FileCopyrightText: Cadasto B.V.
4// SPDX-License-Identifier: Apache-2.0
5//! The FHIR primitive types (<https://hl7.org/fhir/R4/datatypes.html#primitive>).
6
7/// Primitive Type base64Binary
8///
9/// A stream of bytes
10#[derive(Debug, Clone, Default, PartialEq, Eq)]
11pub struct Base64Binary {
12    /// xml:id (or equivalent in JSON)
13    ///
14    /// unique id for the element within a resource (for internal references)
15    pub id: Option<std::string::String>,
16    /// Additional content defined by implementations
17    ///
18    /// May be used to represent additional information that is not part of the
19    /// basic definition of the resource. To make the use of extensions safe and
20    /// manageable, there is a strict set of governance applied to the definition
21    /// and use of extensions. Though any implementer can define an extension, there
22    /// is a set of requirements that SHALL be met as part of the definition of the
23    /// extension.
24    pub extension: Vec<super::extension::Extension>,
25    /// Primitive value for base64Binary
26    ///
27    /// The actual value
28    pub value: Option<std::string::String>,
29}
30impl From<std::string::String> for Base64Binary {
31    fn from(value: std::string::String) -> Self {
32        Self {
33            value: Some(value),
34            ..Self::default()
35        }
36    }
37}
38impl From<&str> for Base64Binary {
39    fn from(value: &str) -> Self {
40        Self::from(std::string::String::from(value))
41    }
42}
43
44/// The lexical form of the FHIR primitive `base64Binary`, anchored to the whole value.
45///
46/// The `regex` extension of `base64Binary.value` states it (<https://hl7.org/fhir/R4/datatypes.html#primitive>),
47/// and the form is an XML Schema pattern, where `\s` is the space, the tab,
48/// the carriage return and the line feed alone (<https://www.w3.org/TR/xmlschema-2/#regexs>).
49#[expect(
50    clippy::expect_used,
51    reason = "the emitter compiles every lexical form it writes, so the pattern holds"
52)]
53static BASE64_BINARY_LEXICAL_FORM: std::sync::LazyLock<regex::bytes::Regex> =
54    std::sync::LazyLock::new(|| {
55        regex::bytes::RegexBuilder::new(r"^(?:(\s*([0-9a-zA-Z\+/=]){4}\s*)+)$")
56            .unicode(false)
57            .build()
58            .expect("the lexical form of `base64Binary` should compile")
59    });
60
61/// Hands back `text` when it keeps the lexical form of `base64Binary`.
62///
63/// # Errors
64///
65/// Returns [`super::super::codec::DecodeErrorKind::BadValue`] at `path` for a value outside the form.
66pub(crate) fn checked_base64_binary(
67    text: std::string::String,
68    path: &super::super::codec::Path,
69) -> Result<std::string::String, super::super::codec::DecodeError> {
70    if BASE64_BINARY_LEXICAL_FORM.is_match(text.as_bytes()) {
71        Ok(text)
72    } else {
73        Err(path.error(super::super::codec::DecodeErrorKind::BadValue))
74    }
75}
76
77impl Base64Binary {
78    /// Checks `text` against the lexical form of `base64Binary`, the one the decoder holds a value to.
79    ///
80    /// # Errors
81    ///
82    /// Returns [`super::super::codec::LexicalError`] naming `base64Binary` when `text` is outside the form.
83    pub fn check(text: &str) -> Result<(), super::super::codec::LexicalError> {
84        if BASE64_BINARY_LEXICAL_FORM.is_match(text.as_bytes()) {
85            Ok(())
86        } else {
87            Err(super::super::codec::LexicalError {
88                type_code: "base64Binary",
89            })
90        }
91    }
92}
93
94impl super::super::codec::Primitive for Base64Binary {
95    fn value_json(
96        &self,
97    ) -> Result<Option<super::super::codec::Value>, super::super::codec::EncodeError> {
98        Ok(self
99            .value
100            .as_ref()
101            .map(|v| super::super::codec::Value::String(v.clone())))
102    }
103
104    fn element_json(
105        &self,
106    ) -> Result<Option<super::super::codec::Value>, super::super::codec::EncodeError> {
107        if self.id.is_none() && self.extension.is_empty() {
108            return Ok(None);
109        }
110        let mut object = super::super::codec::Object::new();
111        if let Some(id) = &self.id {
112            object.insert(
113                std::string::String::from("id"),
114                super::super::codec::Value::String(id.clone()),
115            );
116        }
117        if !self.extension.is_empty() {
118            let mut items = Vec::with_capacity(self.extension.len());
119            for item in &self.extension {
120                items.push(super::super::codec::Value::Object(
121                    super::super::codec::Json::to_json(item)?,
122                ));
123            }
124            object.insert(
125                std::string::String::from("extension"),
126                super::super::codec::Value::Array(items),
127            );
128        }
129        Ok(Some(super::super::codec::Value::Object(object)))
130    }
131
132    fn has_value(&self) -> bool {
133        self.value.is_some()
134    }
135
136    fn has_element(&self) -> bool {
137        self.id.is_some() || !self.extension.is_empty()
138    }
139
140    fn serialize_value<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
141        match self.value.as_ref() {
142            Some(v) => serde::Serializer::serialize_str(serializer, v),
143            None => serde::Serializer::serialize_none(serializer),
144        }
145    }
146
147    fn serialize_element<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
148        if self.id.is_none() && self.extension.is_empty() {
149            return serde::Serializer::serialize_none(serializer);
150        }
151        let mut map = serde::Serializer::serialize_map(serializer, None)?;
152        if !self.extension.is_empty() {
153            serde::ser::SerializeMap::serialize_entry(&mut map, "extension", &self.extension)?;
154        }
155        if let Some(id) = &self.id {
156            serde::ser::SerializeMap::serialize_entry(&mut map, "id", id)?;
157        }
158        serde::ser::SerializeMap::end(map)
159    }
160
161    fn from_json_parts(
162        value: Option<&super::super::codec::Value>,
163        element: Option<&super::super::codec::Value>,
164        path: &mut super::super::codec::Path,
165    ) -> Result<Self, super::super::codec::DecodeError> {
166        if value.is_none() && element.is_none() && !path.is_lenient() {
167            return Err(path.error(super::super::codec::DecodeErrorKind::MissingProperty));
168        }
169        let value = match value {
170            Some(value) => {
171                let value = super::super::codec::expect_single(value, path)?;
172                Some(checked_base64_binary(
173                    super::super::codec::expect_string(value, path)?,
174                    path,
175                )?)
176            }
177            None => None,
178        };
179        let mut id = None;
180        let mut extension = Vec::new();
181        if let Some(element) = element {
182            let object = super::super::codec::expect_object(element, path)?;
183            for (key, item) in object {
184                match key.as_str() {
185                    "id" => {
186                        id = Some(path.with("id", |path| {
187                            super::primitives::checked_string(
188                                super::super::codec::expect_string(item, path)?,
189                                path,
190                            )
191                        })?);
192                    }
193                    "extension" => {
194                        for (index, entry) in super::super::codec::expect_array(item, path)?
195                            .iter()
196                            .enumerate()
197                        {
198                            extension.push(path.with_index("extension", index, |path| {
199                                super::super::codec::Json::from_json(
200                                    super::super::codec::expect_object(entry, path)?,
201                                    path,
202                                )
203                            })?);
204                        }
205                    }
206                    _ => {
207                        return path.with(key, |path| {
208                            Err(path.error(super::super::codec::DecodeErrorKind::UnknownProperty))
209                        });
210                    }
211                }
212            }
213        }
214        Ok(Self {
215            id,
216            extension,
217            value,
218        })
219    }
220}
221
222/// Primitive Type boolean
223///
224/// Value of "true" or "false"
225#[derive(Debug, Clone, Default, PartialEq, Eq)]
226pub struct Boolean {
227    /// xml:id (or equivalent in JSON)
228    ///
229    /// unique id for the element within a resource (for internal references)
230    pub id: Option<std::string::String>,
231    /// Additional content defined by implementations
232    ///
233    /// May be used to represent additional information that is not part of the
234    /// basic definition of the resource. To make the use of extensions safe and
235    /// manageable, there is a strict set of governance applied to the definition
236    /// and use of extensions. Though any implementer can define an extension, there
237    /// is a set of requirements that SHALL be met as part of the definition of the
238    /// extension.
239    pub extension: Vec<super::extension::Extension>,
240    /// Primitive value for boolean
241    ///
242    /// The actual value
243    pub value: Option<bool>,
244}
245impl From<bool> for Boolean {
246    fn from(value: bool) -> Self {
247        Self {
248            value: Some(value),
249            ..Self::default()
250        }
251    }
252}
253
254impl super::super::codec::Primitive for Boolean {
255    fn value_json(
256        &self,
257    ) -> Result<Option<super::super::codec::Value>, super::super::codec::EncodeError> {
258        Ok(self
259            .value
260            .as_ref()
261            .map(|v| super::super::codec::Value::Bool(*v)))
262    }
263
264    fn element_json(
265        &self,
266    ) -> Result<Option<super::super::codec::Value>, super::super::codec::EncodeError> {
267        if self.id.is_none() && self.extension.is_empty() {
268            return Ok(None);
269        }
270        let mut object = super::super::codec::Object::new();
271        if let Some(id) = &self.id {
272            object.insert(
273                std::string::String::from("id"),
274                super::super::codec::Value::String(id.clone()),
275            );
276        }
277        if !self.extension.is_empty() {
278            let mut items = Vec::with_capacity(self.extension.len());
279            for item in &self.extension {
280                items.push(super::super::codec::Value::Object(
281                    super::super::codec::Json::to_json(item)?,
282                ));
283            }
284            object.insert(
285                std::string::String::from("extension"),
286                super::super::codec::Value::Array(items),
287            );
288        }
289        Ok(Some(super::super::codec::Value::Object(object)))
290    }
291
292    fn has_value(&self) -> bool {
293        self.value.is_some()
294    }
295
296    fn has_element(&self) -> bool {
297        self.id.is_some() || !self.extension.is_empty()
298    }
299
300    fn serialize_value<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
301        match self.value.as_ref() {
302            Some(v) => serde::Serializer::serialize_bool(serializer, *v),
303            None => serde::Serializer::serialize_none(serializer),
304        }
305    }
306
307    fn serialize_element<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
308        if self.id.is_none() && self.extension.is_empty() {
309            return serde::Serializer::serialize_none(serializer);
310        }
311        let mut map = serde::Serializer::serialize_map(serializer, None)?;
312        if !self.extension.is_empty() {
313            serde::ser::SerializeMap::serialize_entry(&mut map, "extension", &self.extension)?;
314        }
315        if let Some(id) = &self.id {
316            serde::ser::SerializeMap::serialize_entry(&mut map, "id", id)?;
317        }
318        serde::ser::SerializeMap::end(map)
319    }
320
321    fn from_json_parts(
322        value: Option<&super::super::codec::Value>,
323        element: Option<&super::super::codec::Value>,
324        path: &mut super::super::codec::Path,
325    ) -> Result<Self, super::super::codec::DecodeError> {
326        if value.is_none() && element.is_none() && !path.is_lenient() {
327            return Err(path.error(super::super::codec::DecodeErrorKind::MissingProperty));
328        }
329        let value = match value {
330            Some(value) => {
331                let value = super::super::codec::expect_single(value, path)?;
332                Some(super::super::codec::expect_bool(value, path)?)
333            }
334            None => None,
335        };
336        let mut id = None;
337        let mut extension = Vec::new();
338        if let Some(element) = element {
339            let object = super::super::codec::expect_object(element, path)?;
340            for (key, item) in object {
341                match key.as_str() {
342                    "id" => {
343                        id = Some(path.with("id", |path| {
344                            super::primitives::checked_string(
345                                super::super::codec::expect_string(item, path)?,
346                                path,
347                            )
348                        })?);
349                    }
350                    "extension" => {
351                        for (index, entry) in super::super::codec::expect_array(item, path)?
352                            .iter()
353                            .enumerate()
354                        {
355                            extension.push(path.with_index("extension", index, |path| {
356                                super::super::codec::Json::from_json(
357                                    super::super::codec::expect_object(entry, path)?,
358                                    path,
359                                )
360                            })?);
361                        }
362                    }
363                    _ => {
364                        return path.with(key, |path| {
365                            Err(path.error(super::super::codec::DecodeErrorKind::UnknownProperty))
366                        });
367                    }
368                }
369            }
370        }
371        Ok(Self {
372            id,
373            extension,
374            value,
375        })
376    }
377}
378
379/// Primitive Type canonical
380///
381/// A URI that is a reference to a canonical URL on a FHIR resource
382#[derive(Debug, Clone, Default, PartialEq, Eq)]
383pub struct Canonical {
384    /// xml:id (or equivalent in JSON)
385    ///
386    /// unique id for the element within a resource (for internal references)
387    pub id: Option<std::string::String>,
388    /// Additional content defined by implementations
389    ///
390    /// May be used to represent additional information that is not part of the
391    /// basic definition of the resource. To make the use of extensions safe and
392    /// manageable, there is a strict set of governance applied to the definition
393    /// and use of extensions. Though any implementer can define an extension, there
394    /// is a set of requirements that SHALL be met as part of the definition of the
395    /// extension.
396    pub extension: Vec<super::extension::Extension>,
397    /// Primitive value for canonical
398    pub value: Option<std::string::String>,
399}
400impl From<std::string::String> for Canonical {
401    fn from(value: std::string::String) -> Self {
402        Self {
403            value: Some(value),
404            ..Self::default()
405        }
406    }
407}
408impl From<&str> for Canonical {
409    fn from(value: &str) -> Self {
410        Self::from(std::string::String::from(value))
411    }
412}
413
414/// The lexical form of the FHIR primitive `canonical`, anchored to the whole value.
415///
416/// The `regex` extension of `canonical.value` states it (<https://hl7.org/fhir/R4/datatypes.html#primitive>),
417/// and the form is an XML Schema pattern, where `\s` is the space, the tab,
418/// the carriage return and the line feed alone (<https://www.w3.org/TR/xmlschema-2/#regexs>).
419#[expect(
420    clippy::expect_used,
421    reason = "the emitter compiles every lexical form it writes, so the pattern holds"
422)]
423static CANONICAL_LEXICAL_FORM: std::sync::LazyLock<regex::bytes::Regex> =
424    std::sync::LazyLock::new(|| {
425        regex::bytes::RegexBuilder::new(r"^(?:\S*)$")
426            .unicode(false)
427            .build()
428            .expect("the lexical form of `canonical` should compile")
429    });
430
431/// Hands back `text` when it keeps the lexical form of `canonical`.
432///
433/// # Errors
434///
435/// Returns [`super::super::codec::DecodeErrorKind::BadValue`] at `path` for a value outside the form.
436pub(crate) fn checked_canonical(
437    text: std::string::String,
438    path: &super::super::codec::Path,
439) -> Result<std::string::String, super::super::codec::DecodeError> {
440    if CANONICAL_LEXICAL_FORM.is_match(text.as_bytes()) {
441        Ok(text)
442    } else {
443        Err(path.error(super::super::codec::DecodeErrorKind::BadValue))
444    }
445}
446
447impl Canonical {
448    /// Checks `text` against the lexical form of `canonical`, the one the decoder holds a value to.
449    ///
450    /// # Errors
451    ///
452    /// Returns [`super::super::codec::LexicalError`] naming `canonical` when `text` is outside the form.
453    pub fn check(text: &str) -> Result<(), super::super::codec::LexicalError> {
454        if CANONICAL_LEXICAL_FORM.is_match(text.as_bytes()) {
455            Ok(())
456        } else {
457            Err(super::super::codec::LexicalError {
458                type_code: "canonical",
459            })
460        }
461    }
462}
463
464impl super::super::codec::Primitive for Canonical {
465    fn value_json(
466        &self,
467    ) -> Result<Option<super::super::codec::Value>, super::super::codec::EncodeError> {
468        Ok(self
469            .value
470            .as_ref()
471            .map(|v| super::super::codec::Value::String(v.clone())))
472    }
473
474    fn element_json(
475        &self,
476    ) -> Result<Option<super::super::codec::Value>, super::super::codec::EncodeError> {
477        if self.id.is_none() && self.extension.is_empty() {
478            return Ok(None);
479        }
480        let mut object = super::super::codec::Object::new();
481        if let Some(id) = &self.id {
482            object.insert(
483                std::string::String::from("id"),
484                super::super::codec::Value::String(id.clone()),
485            );
486        }
487        if !self.extension.is_empty() {
488            let mut items = Vec::with_capacity(self.extension.len());
489            for item in &self.extension {
490                items.push(super::super::codec::Value::Object(
491                    super::super::codec::Json::to_json(item)?,
492                ));
493            }
494            object.insert(
495                std::string::String::from("extension"),
496                super::super::codec::Value::Array(items),
497            );
498        }
499        Ok(Some(super::super::codec::Value::Object(object)))
500    }
501
502    fn has_value(&self) -> bool {
503        self.value.is_some()
504    }
505
506    fn has_element(&self) -> bool {
507        self.id.is_some() || !self.extension.is_empty()
508    }
509
510    fn serialize_value<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
511        match self.value.as_ref() {
512            Some(v) => serde::Serializer::serialize_str(serializer, v),
513            None => serde::Serializer::serialize_none(serializer),
514        }
515    }
516
517    fn serialize_element<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
518        if self.id.is_none() && self.extension.is_empty() {
519            return serde::Serializer::serialize_none(serializer);
520        }
521        let mut map = serde::Serializer::serialize_map(serializer, None)?;
522        if !self.extension.is_empty() {
523            serde::ser::SerializeMap::serialize_entry(&mut map, "extension", &self.extension)?;
524        }
525        if let Some(id) = &self.id {
526            serde::ser::SerializeMap::serialize_entry(&mut map, "id", id)?;
527        }
528        serde::ser::SerializeMap::end(map)
529    }
530
531    fn from_json_parts(
532        value: Option<&super::super::codec::Value>,
533        element: Option<&super::super::codec::Value>,
534        path: &mut super::super::codec::Path,
535    ) -> Result<Self, super::super::codec::DecodeError> {
536        if value.is_none() && element.is_none() && !path.is_lenient() {
537            return Err(path.error(super::super::codec::DecodeErrorKind::MissingProperty));
538        }
539        let value = match value {
540            Some(value) => {
541                let value = super::super::codec::expect_single(value, path)?;
542                Some(checked_canonical(
543                    super::super::codec::expect_string(value, path)?,
544                    path,
545                )?)
546            }
547            None => None,
548        };
549        let mut id = None;
550        let mut extension = Vec::new();
551        if let Some(element) = element {
552            let object = super::super::codec::expect_object(element, path)?;
553            for (key, item) in object {
554                match key.as_str() {
555                    "id" => {
556                        id = Some(path.with("id", |path| {
557                            super::primitives::checked_string(
558                                super::super::codec::expect_string(item, path)?,
559                                path,
560                            )
561                        })?);
562                    }
563                    "extension" => {
564                        for (index, entry) in super::super::codec::expect_array(item, path)?
565                            .iter()
566                            .enumerate()
567                        {
568                            extension.push(path.with_index("extension", index, |path| {
569                                super::super::codec::Json::from_json(
570                                    super::super::codec::expect_object(entry, path)?,
571                                    path,
572                                )
573                            })?);
574                        }
575                    }
576                    _ => {
577                        return path.with(key, |path| {
578                            Err(path.error(super::super::codec::DecodeErrorKind::UnknownProperty))
579                        });
580                    }
581                }
582            }
583        }
584        Ok(Self {
585            id,
586            extension,
587            value,
588        })
589    }
590}
591
592/// Primitive Type code
593///
594/// A string which has at least one character and no leading or trailing
595/// whitespace and where there is no whitespace other than single spaces in the
596/// contents
597#[derive(Debug, Clone, Default, PartialEq, Eq)]
598pub struct Code {
599    /// xml:id (or equivalent in JSON)
600    ///
601    /// unique id for the element within a resource (for internal references)
602    pub id: Option<std::string::String>,
603    /// Additional content defined by implementations
604    ///
605    /// May be used to represent additional information that is not part of the
606    /// basic definition of the resource. To make the use of extensions safe and
607    /// manageable, there is a strict set of governance applied to the definition
608    /// and use of extensions. Though any implementer can define an extension, there
609    /// is a set of requirements that SHALL be met as part of the definition of the
610    /// extension.
611    pub extension: Vec<super::extension::Extension>,
612    /// Primitive value for code
613    pub value: Option<std::string::String>,
614}
615impl From<std::string::String> for Code {
616    fn from(value: std::string::String) -> Self {
617        Self {
618            value: Some(value),
619            ..Self::default()
620        }
621    }
622}
623impl From<&str> for Code {
624    fn from(value: &str) -> Self {
625        Self::from(std::string::String::from(value))
626    }
627}
628
629/// The lexical form of the FHIR primitive `code`, anchored to the whole value.
630///
631/// The `regex` extension of `code.value` states it (<https://hl7.org/fhir/R4/datatypes.html#primitive>),
632/// and the form is an XML Schema pattern, where `\s` is the space, the tab,
633/// the carriage return and the line feed alone (<https://www.w3.org/TR/xmlschema-2/#regexs>).
634#[expect(
635    clippy::expect_used,
636    reason = "the emitter compiles every lexical form it writes, so the pattern holds"
637)]
638static CODE_LEXICAL_FORM: std::sync::LazyLock<regex::bytes::Regex> =
639    std::sync::LazyLock::new(|| {
640        regex::bytes::RegexBuilder::new(r"^(?:[^\s]+(\s[^\s]+)*)$")
641            .unicode(false)
642            .build()
643            .expect("the lexical form of `code` should compile")
644    });
645
646/// Hands back `text` when it keeps the lexical form of `code`.
647///
648/// # Errors
649///
650/// Returns [`super::super::codec::DecodeErrorKind::BadValue`] at `path` for a value outside the form.
651pub(crate) fn checked_code(
652    text: std::string::String,
653    path: &super::super::codec::Path,
654) -> Result<std::string::String, super::super::codec::DecodeError> {
655    if CODE_LEXICAL_FORM.is_match(text.as_bytes()) {
656        Ok(text)
657    } else {
658        Err(path.error(super::super::codec::DecodeErrorKind::BadValue))
659    }
660}
661
662impl Code {
663    /// Checks `text` against the lexical form of `code`, the one the decoder holds a value to.
664    ///
665    /// # Errors
666    ///
667    /// Returns [`super::super::codec::LexicalError`] naming `code` when `text` is outside the form.
668    pub fn check(text: &str) -> Result<(), super::super::codec::LexicalError> {
669        if CODE_LEXICAL_FORM.is_match(text.as_bytes()) {
670            Ok(())
671        } else {
672            Err(super::super::codec::LexicalError { type_code: "code" })
673        }
674    }
675}
676
677impl super::super::codec::Primitive for Code {
678    fn value_json(
679        &self,
680    ) -> Result<Option<super::super::codec::Value>, super::super::codec::EncodeError> {
681        Ok(self
682            .value
683            .as_ref()
684            .map(|v| super::super::codec::Value::String(v.clone())))
685    }
686
687    fn element_json(
688        &self,
689    ) -> Result<Option<super::super::codec::Value>, super::super::codec::EncodeError> {
690        if self.id.is_none() && self.extension.is_empty() {
691            return Ok(None);
692        }
693        let mut object = super::super::codec::Object::new();
694        if let Some(id) = &self.id {
695            object.insert(
696                std::string::String::from("id"),
697                super::super::codec::Value::String(id.clone()),
698            );
699        }
700        if !self.extension.is_empty() {
701            let mut items = Vec::with_capacity(self.extension.len());
702            for item in &self.extension {
703                items.push(super::super::codec::Value::Object(
704                    super::super::codec::Json::to_json(item)?,
705                ));
706            }
707            object.insert(
708                std::string::String::from("extension"),
709                super::super::codec::Value::Array(items),
710            );
711        }
712        Ok(Some(super::super::codec::Value::Object(object)))
713    }
714
715    fn has_value(&self) -> bool {
716        self.value.is_some()
717    }
718
719    fn has_element(&self) -> bool {
720        self.id.is_some() || !self.extension.is_empty()
721    }
722
723    fn serialize_value<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
724        match self.value.as_ref() {
725            Some(v) => serde::Serializer::serialize_str(serializer, v),
726            None => serde::Serializer::serialize_none(serializer),
727        }
728    }
729
730    fn serialize_element<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
731        if self.id.is_none() && self.extension.is_empty() {
732            return serde::Serializer::serialize_none(serializer);
733        }
734        let mut map = serde::Serializer::serialize_map(serializer, None)?;
735        if !self.extension.is_empty() {
736            serde::ser::SerializeMap::serialize_entry(&mut map, "extension", &self.extension)?;
737        }
738        if let Some(id) = &self.id {
739            serde::ser::SerializeMap::serialize_entry(&mut map, "id", id)?;
740        }
741        serde::ser::SerializeMap::end(map)
742    }
743
744    fn from_json_parts(
745        value: Option<&super::super::codec::Value>,
746        element: Option<&super::super::codec::Value>,
747        path: &mut super::super::codec::Path,
748    ) -> Result<Self, super::super::codec::DecodeError> {
749        if value.is_none() && element.is_none() && !path.is_lenient() {
750            return Err(path.error(super::super::codec::DecodeErrorKind::MissingProperty));
751        }
752        let value = match value {
753            Some(value) => {
754                let value = super::super::codec::expect_single(value, path)?;
755                Some(checked_code(
756                    super::super::codec::expect_string(value, path)?,
757                    path,
758                )?)
759            }
760            None => None,
761        };
762        let mut id = None;
763        let mut extension = Vec::new();
764        if let Some(element) = element {
765            let object = super::super::codec::expect_object(element, path)?;
766            for (key, item) in object {
767                match key.as_str() {
768                    "id" => {
769                        id = Some(path.with("id", |path| {
770                            super::primitives::checked_string(
771                                super::super::codec::expect_string(item, path)?,
772                                path,
773                            )
774                        })?);
775                    }
776                    "extension" => {
777                        for (index, entry) in super::super::codec::expect_array(item, path)?
778                            .iter()
779                            .enumerate()
780                        {
781                            extension.push(path.with_index("extension", index, |path| {
782                                super::super::codec::Json::from_json(
783                                    super::super::codec::expect_object(entry, path)?,
784                                    path,
785                                )
786                            })?);
787                        }
788                    }
789                    _ => {
790                        return path.with(key, |path| {
791                            Err(path.error(super::super::codec::DecodeErrorKind::UnknownProperty))
792                        });
793                    }
794                }
795            }
796        }
797        Ok(Self {
798            id,
799            extension,
800            value,
801        })
802    }
803}
804
805/// Primitive Type date
806///
807/// A date or partial date (e.g. just year or year + month). There is no time
808/// zone. The format is a union of the schema types gYear, gYearMonth and date.
809/// Dates SHALL be valid dates.
810#[derive(Debug, Clone, Default, PartialEq, Eq)]
811pub struct Date {
812    /// xml:id (or equivalent in JSON)
813    ///
814    /// unique id for the element within a resource (for internal references)
815    pub id: Option<std::string::String>,
816    /// Additional content defined by implementations
817    ///
818    /// May be used to represent additional information that is not part of the
819    /// basic definition of the resource. To make the use of extensions safe and
820    /// manageable, there is a strict set of governance applied to the definition
821    /// and use of extensions. Though any implementer can define an extension, there
822    /// is a set of requirements that SHALL be met as part of the definition of the
823    /// extension.
824    pub extension: Vec<super::extension::Extension>,
825    /// Primitive value for date
826    ///
827    /// The actual value
828    pub value: Option<std::string::String>,
829}
830impl From<std::string::String> for Date {
831    fn from(value: std::string::String) -> Self {
832        Self {
833            value: Some(value),
834            ..Self::default()
835        }
836    }
837}
838impl From<&str> for Date {
839    fn from(value: &str) -> Self {
840        Self::from(std::string::String::from(value))
841    }
842}
843
844/// The lexical form of the FHIR primitive `date`, anchored to the whole value.
845///
846/// The `regex` extension of `date.value` states it (<https://hl7.org/fhir/R4/datatypes.html#primitive>),
847/// and the form is an XML Schema pattern, where `\s` is the space, the tab,
848/// the carriage return and the line feed alone (<https://www.w3.org/TR/xmlschema-2/#regexs>).
849#[expect(
850    clippy::expect_used,
851    reason = "the emitter compiles every lexical form it writes, so the pattern holds"
852)]
853static DATE_LEXICAL_FORM: std::sync::LazyLock<regex::bytes::Regex> = std::sync::LazyLock::new(
854    || {
855        regex::bytes::RegexBuilder::new(r"^(?:([0-9]([0-9]([0-9][1-9]|[1-9]0)|[1-9]00)|[1-9]000)(-(0[1-9]|1[0-2])(-(0[1-9]|[1-2][0-9]|3[0-1]))?)?)$")
856        .unicode(false)
857        .build()
858        .expect("the lexical form of `date` should compile")
859    },
860);
861
862/// Hands back `text` when it keeps the lexical form of `date`.
863///
864/// # Errors
865///
866/// Returns [`super::super::codec::DecodeErrorKind::BadValue`] at `path` for a value outside the form.
867pub(crate) fn checked_date(
868    text: std::string::String,
869    path: &super::super::codec::Path,
870) -> Result<std::string::String, super::super::codec::DecodeError> {
871    if DATE_LEXICAL_FORM.is_match(text.as_bytes()) {
872        Ok(text)
873    } else {
874        Err(path.error(super::super::codec::DecodeErrorKind::BadValue))
875    }
876}
877
878impl Date {
879    /// Checks `text` against the lexical form of `date`, the one the decoder holds a value to.
880    ///
881    /// # Errors
882    ///
883    /// Returns [`super::super::codec::LexicalError`] naming `date` when `text` is outside the form.
884    pub fn check(text: &str) -> Result<(), super::super::codec::LexicalError> {
885        if DATE_LEXICAL_FORM.is_match(text.as_bytes()) {
886            Ok(())
887        } else {
888            Err(super::super::codec::LexicalError { type_code: "date" })
889        }
890    }
891}
892
893impl super::super::codec::Primitive for Date {
894    fn value_json(
895        &self,
896    ) -> Result<Option<super::super::codec::Value>, super::super::codec::EncodeError> {
897        Ok(self
898            .value
899            .as_ref()
900            .map(|v| super::super::codec::Value::String(v.clone())))
901    }
902
903    fn element_json(
904        &self,
905    ) -> Result<Option<super::super::codec::Value>, super::super::codec::EncodeError> {
906        if self.id.is_none() && self.extension.is_empty() {
907            return Ok(None);
908        }
909        let mut object = super::super::codec::Object::new();
910        if let Some(id) = &self.id {
911            object.insert(
912                std::string::String::from("id"),
913                super::super::codec::Value::String(id.clone()),
914            );
915        }
916        if !self.extension.is_empty() {
917            let mut items = Vec::with_capacity(self.extension.len());
918            for item in &self.extension {
919                items.push(super::super::codec::Value::Object(
920                    super::super::codec::Json::to_json(item)?,
921                ));
922            }
923            object.insert(
924                std::string::String::from("extension"),
925                super::super::codec::Value::Array(items),
926            );
927        }
928        Ok(Some(super::super::codec::Value::Object(object)))
929    }
930
931    fn has_value(&self) -> bool {
932        self.value.is_some()
933    }
934
935    fn has_element(&self) -> bool {
936        self.id.is_some() || !self.extension.is_empty()
937    }
938
939    fn serialize_value<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
940        match self.value.as_ref() {
941            Some(v) => serde::Serializer::serialize_str(serializer, v),
942            None => serde::Serializer::serialize_none(serializer),
943        }
944    }
945
946    fn serialize_element<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
947        if self.id.is_none() && self.extension.is_empty() {
948            return serde::Serializer::serialize_none(serializer);
949        }
950        let mut map = serde::Serializer::serialize_map(serializer, None)?;
951        if !self.extension.is_empty() {
952            serde::ser::SerializeMap::serialize_entry(&mut map, "extension", &self.extension)?;
953        }
954        if let Some(id) = &self.id {
955            serde::ser::SerializeMap::serialize_entry(&mut map, "id", id)?;
956        }
957        serde::ser::SerializeMap::end(map)
958    }
959
960    fn from_json_parts(
961        value: Option<&super::super::codec::Value>,
962        element: Option<&super::super::codec::Value>,
963        path: &mut super::super::codec::Path,
964    ) -> Result<Self, super::super::codec::DecodeError> {
965        if value.is_none() && element.is_none() && !path.is_lenient() {
966            return Err(path.error(super::super::codec::DecodeErrorKind::MissingProperty));
967        }
968        let value = match value {
969            Some(value) => {
970                let value = super::super::codec::expect_single(value, path)?;
971                Some(checked_date(
972                    super::super::codec::expect_string(value, path)?,
973                    path,
974                )?)
975            }
976            None => None,
977        };
978        let mut id = None;
979        let mut extension = Vec::new();
980        if let Some(element) = element {
981            let object = super::super::codec::expect_object(element, path)?;
982            for (key, item) in object {
983                match key.as_str() {
984                    "id" => {
985                        id = Some(path.with("id", |path| {
986                            super::primitives::checked_string(
987                                super::super::codec::expect_string(item, path)?,
988                                path,
989                            )
990                        })?);
991                    }
992                    "extension" => {
993                        for (index, entry) in super::super::codec::expect_array(item, path)?
994                            .iter()
995                            .enumerate()
996                        {
997                            extension.push(path.with_index("extension", index, |path| {
998                                super::super::codec::Json::from_json(
999                                    super::super::codec::expect_object(entry, path)?,
1000                                    path,
1001                                )
1002                            })?);
1003                        }
1004                    }
1005                    _ => {
1006                        return path.with(key, |path| {
1007                            Err(path.error(super::super::codec::DecodeErrorKind::UnknownProperty))
1008                        });
1009                    }
1010                }
1011            }
1012        }
1013        Ok(Self {
1014            id,
1015            extension,
1016            value,
1017        })
1018    }
1019}
1020
1021/// Primitive Type dateTime
1022///
1023/// A date, date-time or partial date (e.g. just year or year + month). If hours
1024/// and minutes are specified, a time zone SHALL be populated. The format is a
1025/// union of the schema types gYear, gYearMonth, date and dateTime. Seconds must
1026/// be provided due to schema type constraints but may be zero-filled and may be
1027/// ignored. Dates SHALL be valid dates.
1028#[derive(Debug, Clone, Default, PartialEq, Eq)]
1029pub struct DateTime {
1030    /// xml:id (or equivalent in JSON)
1031    ///
1032    /// unique id for the element within a resource (for internal references)
1033    pub id: Option<std::string::String>,
1034    /// Additional content defined by implementations
1035    ///
1036    /// May be used to represent additional information that is not part of the
1037    /// basic definition of the resource. To make the use of extensions safe and
1038    /// manageable, there is a strict set of governance applied to the definition
1039    /// and use of extensions. Though any implementer can define an extension, there
1040    /// is a set of requirements that SHALL be met as part of the definition of the
1041    /// extension.
1042    pub extension: Vec<super::extension::Extension>,
1043    /// Primitive value for dateTime
1044    ///
1045    /// The actual value
1046    pub value: Option<std::string::String>,
1047}
1048impl From<std::string::String> for DateTime {
1049    fn from(value: std::string::String) -> Self {
1050        Self {
1051            value: Some(value),
1052            ..Self::default()
1053        }
1054    }
1055}
1056impl From<&str> for DateTime {
1057    fn from(value: &str) -> Self {
1058        Self::from(std::string::String::from(value))
1059    }
1060}
1061
1062/// The lexical form of the FHIR primitive `dateTime`, anchored to the whole value.
1063///
1064/// The `regex` extension of `dateTime.value` states it (<https://hl7.org/fhir/R4/datatypes.html#primitive>),
1065/// and the form is an XML Schema pattern, where `\s` is the space, the tab,
1066/// the carriage return and the line feed alone (<https://www.w3.org/TR/xmlschema-2/#regexs>).
1067#[expect(
1068    clippy::expect_used,
1069    reason = "the emitter compiles every lexical form it writes, so the pattern holds"
1070)]
1071static DATE_TIME_LEXICAL_FORM: std::sync::LazyLock<regex::bytes::Regex> = std::sync::LazyLock::new(
1072    || {
1073        regex::bytes::RegexBuilder::new(r"^(?:([0-9]([0-9]([0-9][1-9]|[1-9]0)|[1-9]00)|[1-9]000)(-(0[1-9]|1[0-2])(-(0[1-9]|[1-2][0-9]|3[0-1])(T([01][0-9]|2[0-3]):[0-5][0-9]:([0-5][0-9]|60)(\.[0-9]+)?(Z|(\+|-)((0[0-9]|1[0-3]):[0-5][0-9]|14:00)))?)?)?)$")
1074        .unicode(false)
1075        .build()
1076        .expect("the lexical form of `dateTime` should compile")
1077    },
1078);
1079
1080/// Hands back `text` when it keeps the lexical form of `dateTime`.
1081///
1082/// # Errors
1083///
1084/// Returns [`super::super::codec::DecodeErrorKind::BadValue`] at `path` for a value outside the form.
1085pub(crate) fn checked_date_time(
1086    text: std::string::String,
1087    path: &super::super::codec::Path,
1088) -> Result<std::string::String, super::super::codec::DecodeError> {
1089    if DATE_TIME_LEXICAL_FORM.is_match(text.as_bytes()) {
1090        Ok(text)
1091    } else {
1092        Err(path.error(super::super::codec::DecodeErrorKind::BadValue))
1093    }
1094}
1095
1096impl DateTime {
1097    /// Checks `text` against the lexical form of `dateTime`, the one the decoder holds a value to.
1098    ///
1099    /// # Errors
1100    ///
1101    /// Returns [`super::super::codec::LexicalError`] naming `dateTime` when `text` is outside the form.
1102    pub fn check(text: &str) -> Result<(), super::super::codec::LexicalError> {
1103        if DATE_TIME_LEXICAL_FORM.is_match(text.as_bytes()) {
1104            Ok(())
1105        } else {
1106            Err(super::super::codec::LexicalError {
1107                type_code: "dateTime",
1108            })
1109        }
1110    }
1111}
1112
1113impl super::super::codec::Primitive for DateTime {
1114    fn value_json(
1115        &self,
1116    ) -> Result<Option<super::super::codec::Value>, super::super::codec::EncodeError> {
1117        Ok(self
1118            .value
1119            .as_ref()
1120            .map(|v| super::super::codec::Value::String(v.clone())))
1121    }
1122
1123    fn element_json(
1124        &self,
1125    ) -> Result<Option<super::super::codec::Value>, super::super::codec::EncodeError> {
1126        if self.id.is_none() && self.extension.is_empty() {
1127            return Ok(None);
1128        }
1129        let mut object = super::super::codec::Object::new();
1130        if let Some(id) = &self.id {
1131            object.insert(
1132                std::string::String::from("id"),
1133                super::super::codec::Value::String(id.clone()),
1134            );
1135        }
1136        if !self.extension.is_empty() {
1137            let mut items = Vec::with_capacity(self.extension.len());
1138            for item in &self.extension {
1139                items.push(super::super::codec::Value::Object(
1140                    super::super::codec::Json::to_json(item)?,
1141                ));
1142            }
1143            object.insert(
1144                std::string::String::from("extension"),
1145                super::super::codec::Value::Array(items),
1146            );
1147        }
1148        Ok(Some(super::super::codec::Value::Object(object)))
1149    }
1150
1151    fn has_value(&self) -> bool {
1152        self.value.is_some()
1153    }
1154
1155    fn has_element(&self) -> bool {
1156        self.id.is_some() || !self.extension.is_empty()
1157    }
1158
1159    fn serialize_value<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
1160        match self.value.as_ref() {
1161            Some(v) => serde::Serializer::serialize_str(serializer, v),
1162            None => serde::Serializer::serialize_none(serializer),
1163        }
1164    }
1165
1166    fn serialize_element<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
1167        if self.id.is_none() && self.extension.is_empty() {
1168            return serde::Serializer::serialize_none(serializer);
1169        }
1170        let mut map = serde::Serializer::serialize_map(serializer, None)?;
1171        if !self.extension.is_empty() {
1172            serde::ser::SerializeMap::serialize_entry(&mut map, "extension", &self.extension)?;
1173        }
1174        if let Some(id) = &self.id {
1175            serde::ser::SerializeMap::serialize_entry(&mut map, "id", id)?;
1176        }
1177        serde::ser::SerializeMap::end(map)
1178    }
1179
1180    fn from_json_parts(
1181        value: Option<&super::super::codec::Value>,
1182        element: Option<&super::super::codec::Value>,
1183        path: &mut super::super::codec::Path,
1184    ) -> Result<Self, super::super::codec::DecodeError> {
1185        if value.is_none() && element.is_none() && !path.is_lenient() {
1186            return Err(path.error(super::super::codec::DecodeErrorKind::MissingProperty));
1187        }
1188        let value = match value {
1189            Some(value) => {
1190                let value = super::super::codec::expect_single(value, path)?;
1191                Some(checked_date_time(
1192                    super::super::codec::expect_string(value, path)?,
1193                    path,
1194                )?)
1195            }
1196            None => None,
1197        };
1198        let mut id = None;
1199        let mut extension = Vec::new();
1200        if let Some(element) = element {
1201            let object = super::super::codec::expect_object(element, path)?;
1202            for (key, item) in object {
1203                match key.as_str() {
1204                    "id" => {
1205                        id = Some(path.with("id", |path| {
1206                            super::primitives::checked_string(
1207                                super::super::codec::expect_string(item, path)?,
1208                                path,
1209                            )
1210                        })?);
1211                    }
1212                    "extension" => {
1213                        for (index, entry) in super::super::codec::expect_array(item, path)?
1214                            .iter()
1215                            .enumerate()
1216                        {
1217                            extension.push(path.with_index("extension", index, |path| {
1218                                super::super::codec::Json::from_json(
1219                                    super::super::codec::expect_object(entry, path)?,
1220                                    path,
1221                                )
1222                            })?);
1223                        }
1224                    }
1225                    _ => {
1226                        return path.with(key, |path| {
1227                            Err(path.error(super::super::codec::DecodeErrorKind::UnknownProperty))
1228                        });
1229                    }
1230                }
1231            }
1232        }
1233        Ok(Self {
1234            id,
1235            extension,
1236            value,
1237        })
1238    }
1239}
1240
1241/// Primitive Type decimal
1242///
1243/// A rational number with implicit precision
1244#[derive(Debug, Clone, Default, PartialEq, Eq)]
1245pub struct Decimal {
1246    /// xml:id (or equivalent in JSON)
1247    ///
1248    /// unique id for the element within a resource (for internal references)
1249    pub id: Option<std::string::String>,
1250    /// Additional content defined by implementations
1251    ///
1252    /// May be used to represent additional information that is not part of the
1253    /// basic definition of the resource. To make the use of extensions safe and
1254    /// manageable, there is a strict set of governance applied to the definition
1255    /// and use of extensions. Though any implementer can define an extension, there
1256    /// is a set of requirements that SHALL be met as part of the definition of the
1257    /// extension.
1258    pub extension: Vec<super::extension::Extension>,
1259    /// Primitive value for decimal
1260    ///
1261    /// The actual value
1262    pub value: Option<std::string::String>,
1263}
1264impl From<std::string::String> for Decimal {
1265    fn from(value: std::string::String) -> Self {
1266        Self {
1267            value: Some(value),
1268            ..Self::default()
1269        }
1270    }
1271}
1272impl From<&str> for Decimal {
1273    fn from(value: &str) -> Self {
1274        Self::from(std::string::String::from(value))
1275    }
1276}
1277
1278impl super::super::codec::Primitive for Decimal {
1279    fn value_json(
1280        &self,
1281    ) -> Result<Option<super::super::codec::Value>, super::super::codec::EncodeError> {
1282        self.value
1283            .as_ref()
1284            .map(|text| {
1285                text.parse::<super::super::codec::Number>()
1286                    .map(super::super::codec::Value::Number)
1287                    .map_err(|_| super::super::codec::EncodeError::BadDecimal {
1288                        text: text.clone(),
1289                    })
1290            })
1291            .transpose()
1292    }
1293
1294    fn element_json(
1295        &self,
1296    ) -> Result<Option<super::super::codec::Value>, super::super::codec::EncodeError> {
1297        if self.id.is_none() && self.extension.is_empty() {
1298            return Ok(None);
1299        }
1300        let mut object = super::super::codec::Object::new();
1301        if let Some(id) = &self.id {
1302            object.insert(
1303                std::string::String::from("id"),
1304                super::super::codec::Value::String(id.clone()),
1305            );
1306        }
1307        if !self.extension.is_empty() {
1308            let mut items = Vec::with_capacity(self.extension.len());
1309            for item in &self.extension {
1310                items.push(super::super::codec::Value::Object(
1311                    super::super::codec::Json::to_json(item)?,
1312                ));
1313            }
1314            object.insert(
1315                std::string::String::from("extension"),
1316                super::super::codec::Value::Array(items),
1317            );
1318        }
1319        Ok(Some(super::super::codec::Value::Object(object)))
1320    }
1321
1322    fn has_value(&self) -> bool {
1323        self.value.is_some()
1324    }
1325
1326    fn has_element(&self) -> bool {
1327        self.id.is_some() || !self.extension.is_empty()
1328    }
1329
1330    fn serialize_value<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
1331        match self.value.as_ref() {
1332            Some(text) => serde::Serialize::serialize(
1333                &text.parse::<super::super::codec::Number>().map_err(|_| {
1334                    <S::Error as serde::ser::Error>::custom(
1335                        super::super::codec::EncodeError::BadDecimal { text: text.clone() },
1336                    )
1337                })?,
1338                serializer,
1339            ),
1340            None => serde::Serializer::serialize_none(serializer),
1341        }
1342    }
1343
1344    fn serialize_element<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
1345        if self.id.is_none() && self.extension.is_empty() {
1346            return serde::Serializer::serialize_none(serializer);
1347        }
1348        let mut map = serde::Serializer::serialize_map(serializer, None)?;
1349        if !self.extension.is_empty() {
1350            serde::ser::SerializeMap::serialize_entry(&mut map, "extension", &self.extension)?;
1351        }
1352        if let Some(id) = &self.id {
1353            serde::ser::SerializeMap::serialize_entry(&mut map, "id", id)?;
1354        }
1355        serde::ser::SerializeMap::end(map)
1356    }
1357
1358    fn from_json_parts(
1359        value: Option<&super::super::codec::Value>,
1360        element: Option<&super::super::codec::Value>,
1361        path: &mut super::super::codec::Path,
1362    ) -> Result<Self, super::super::codec::DecodeError> {
1363        if value.is_none() && element.is_none() && !path.is_lenient() {
1364            return Err(path.error(super::super::codec::DecodeErrorKind::MissingProperty));
1365        }
1366        let value = match value {
1367            Some(value) => {
1368                let value = super::super::codec::expect_single(value, path)?;
1369                Some(super::super::codec::expect_decimal(value, path)?)
1370            }
1371            None => None,
1372        };
1373        let mut id = None;
1374        let mut extension = Vec::new();
1375        if let Some(element) = element {
1376            let object = super::super::codec::expect_object(element, path)?;
1377            for (key, item) in object {
1378                match key.as_str() {
1379                    "id" => {
1380                        id = Some(path.with("id", |path| {
1381                            super::primitives::checked_string(
1382                                super::super::codec::expect_string(item, path)?,
1383                                path,
1384                            )
1385                        })?);
1386                    }
1387                    "extension" => {
1388                        for (index, entry) in super::super::codec::expect_array(item, path)?
1389                            .iter()
1390                            .enumerate()
1391                        {
1392                            extension.push(path.with_index("extension", index, |path| {
1393                                super::super::codec::Json::from_json(
1394                                    super::super::codec::expect_object(entry, path)?,
1395                                    path,
1396                                )
1397                            })?);
1398                        }
1399                    }
1400                    _ => {
1401                        return path.with(key, |path| {
1402                            Err(path.error(super::super::codec::DecodeErrorKind::UnknownProperty))
1403                        });
1404                    }
1405                }
1406            }
1407        }
1408        Ok(Self {
1409            id,
1410            extension,
1411            value,
1412        })
1413    }
1414}
1415
1416/// Primitive Type id
1417///
1418/// Any combination of letters, numerals, "-" and ".", with a length limit of 64
1419/// characters. (This might be an integer, an unprefixed OID, UUID or any other
1420/// identifier pattern that meets these constraints.) Ids are case-insensitive.
1421#[derive(Debug, Clone, Default, PartialEq, Eq)]
1422pub struct Id {
1423    /// xml:id (or equivalent in JSON)
1424    ///
1425    /// unique id for the element within a resource (for internal references)
1426    pub id: Option<std::string::String>,
1427    /// Additional content defined by implementations
1428    ///
1429    /// May be used to represent additional information that is not part of the
1430    /// basic definition of the resource. To make the use of extensions safe and
1431    /// manageable, there is a strict set of governance applied to the definition
1432    /// and use of extensions. Though any implementer can define an extension, there
1433    /// is a set of requirements that SHALL be met as part of the definition of the
1434    /// extension.
1435    pub extension: Vec<super::extension::Extension>,
1436    /// Primitive value for id
1437    pub value: Option<std::string::String>,
1438}
1439impl From<std::string::String> for Id {
1440    fn from(value: std::string::String) -> Self {
1441        Self {
1442            value: Some(value),
1443            ..Self::default()
1444        }
1445    }
1446}
1447impl From<&str> for Id {
1448    fn from(value: &str) -> Self {
1449        Self::from(std::string::String::from(value))
1450    }
1451}
1452
1453/// The lexical form of the FHIR primitive `id`, anchored to the whole value.
1454///
1455/// The `regex` extension of `id.value` states it (<https://hl7.org/fhir/R4/datatypes.html#primitive>),
1456/// and the form is an XML Schema pattern, where `\s` is the space, the tab,
1457/// the carriage return and the line feed alone (<https://www.w3.org/TR/xmlschema-2/#regexs>).
1458#[expect(
1459    clippy::expect_used,
1460    reason = "the emitter compiles every lexical form it writes, so the pattern holds"
1461)]
1462static ID_LEXICAL_FORM: std::sync::LazyLock<regex::bytes::Regex> = std::sync::LazyLock::new(|| {
1463    regex::bytes::RegexBuilder::new(r"^(?:[A-Za-z0-9\-\.]{1,64})$")
1464        .unicode(false)
1465        .build()
1466        .expect("the lexical form of `id` should compile")
1467});
1468
1469/// Hands back `text` when it keeps the lexical form of `id`.
1470///
1471/// # Errors
1472///
1473/// Returns [`super::super::codec::DecodeErrorKind::BadValue`] at `path` for a value outside the form.
1474pub(crate) fn checked_id(
1475    text: std::string::String,
1476    path: &super::super::codec::Path,
1477) -> Result<std::string::String, super::super::codec::DecodeError> {
1478    if ID_LEXICAL_FORM.is_match(text.as_bytes()) {
1479        Ok(text)
1480    } else {
1481        Err(path.error(super::super::codec::DecodeErrorKind::BadValue))
1482    }
1483}
1484
1485impl Id {
1486    /// Checks `text` against the lexical form of `id`, the one the decoder holds a value to.
1487    ///
1488    /// # Errors
1489    ///
1490    /// Returns [`super::super::codec::LexicalError`] naming `id` when `text` is outside the form.
1491    pub fn check(text: &str) -> Result<(), super::super::codec::LexicalError> {
1492        if ID_LEXICAL_FORM.is_match(text.as_bytes()) {
1493            Ok(())
1494        } else {
1495            Err(super::super::codec::LexicalError { type_code: "id" })
1496        }
1497    }
1498}
1499
1500impl super::super::codec::Primitive for Id {
1501    fn value_json(
1502        &self,
1503    ) -> Result<Option<super::super::codec::Value>, super::super::codec::EncodeError> {
1504        Ok(self
1505            .value
1506            .as_ref()
1507            .map(|v| super::super::codec::Value::String(v.clone())))
1508    }
1509
1510    fn element_json(
1511        &self,
1512    ) -> Result<Option<super::super::codec::Value>, super::super::codec::EncodeError> {
1513        if self.id.is_none() && self.extension.is_empty() {
1514            return Ok(None);
1515        }
1516        let mut object = super::super::codec::Object::new();
1517        if let Some(id) = &self.id {
1518            object.insert(
1519                std::string::String::from("id"),
1520                super::super::codec::Value::String(id.clone()),
1521            );
1522        }
1523        if !self.extension.is_empty() {
1524            let mut items = Vec::with_capacity(self.extension.len());
1525            for item in &self.extension {
1526                items.push(super::super::codec::Value::Object(
1527                    super::super::codec::Json::to_json(item)?,
1528                ));
1529            }
1530            object.insert(
1531                std::string::String::from("extension"),
1532                super::super::codec::Value::Array(items),
1533            );
1534        }
1535        Ok(Some(super::super::codec::Value::Object(object)))
1536    }
1537
1538    fn has_value(&self) -> bool {
1539        self.value.is_some()
1540    }
1541
1542    fn has_element(&self) -> bool {
1543        self.id.is_some() || !self.extension.is_empty()
1544    }
1545
1546    fn serialize_value<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
1547        match self.value.as_ref() {
1548            Some(v) => serde::Serializer::serialize_str(serializer, v),
1549            None => serde::Serializer::serialize_none(serializer),
1550        }
1551    }
1552
1553    fn serialize_element<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
1554        if self.id.is_none() && self.extension.is_empty() {
1555            return serde::Serializer::serialize_none(serializer);
1556        }
1557        let mut map = serde::Serializer::serialize_map(serializer, None)?;
1558        if !self.extension.is_empty() {
1559            serde::ser::SerializeMap::serialize_entry(&mut map, "extension", &self.extension)?;
1560        }
1561        if let Some(id) = &self.id {
1562            serde::ser::SerializeMap::serialize_entry(&mut map, "id", id)?;
1563        }
1564        serde::ser::SerializeMap::end(map)
1565    }
1566
1567    fn from_json_parts(
1568        value: Option<&super::super::codec::Value>,
1569        element: Option<&super::super::codec::Value>,
1570        path: &mut super::super::codec::Path,
1571    ) -> Result<Self, super::super::codec::DecodeError> {
1572        if value.is_none() && element.is_none() && !path.is_lenient() {
1573            return Err(path.error(super::super::codec::DecodeErrorKind::MissingProperty));
1574        }
1575        let value = match value {
1576            Some(value) => {
1577                let value = super::super::codec::expect_single(value, path)?;
1578                Some(checked_id(
1579                    super::super::codec::expect_string(value, path)?,
1580                    path,
1581                )?)
1582            }
1583            None => None,
1584        };
1585        let mut id = None;
1586        let mut extension = Vec::new();
1587        if let Some(element) = element {
1588            let object = super::super::codec::expect_object(element, path)?;
1589            for (key, item) in object {
1590                match key.as_str() {
1591                    "id" => {
1592                        id = Some(path.with("id", |path| {
1593                            super::primitives::checked_string(
1594                                super::super::codec::expect_string(item, path)?,
1595                                path,
1596                            )
1597                        })?);
1598                    }
1599                    "extension" => {
1600                        for (index, entry) in super::super::codec::expect_array(item, path)?
1601                            .iter()
1602                            .enumerate()
1603                        {
1604                            extension.push(path.with_index("extension", index, |path| {
1605                                super::super::codec::Json::from_json(
1606                                    super::super::codec::expect_object(entry, path)?,
1607                                    path,
1608                                )
1609                            })?);
1610                        }
1611                    }
1612                    _ => {
1613                        return path.with(key, |path| {
1614                            Err(path.error(super::super::codec::DecodeErrorKind::UnknownProperty))
1615                        });
1616                    }
1617                }
1618            }
1619        }
1620        Ok(Self {
1621            id,
1622            extension,
1623            value,
1624        })
1625    }
1626}
1627
1628/// Primitive Type instant
1629///
1630/// An instant in time - known at least to the second
1631#[derive(Debug, Clone, Default, PartialEq, Eq)]
1632pub struct Instant {
1633    /// xml:id (or equivalent in JSON)
1634    ///
1635    /// unique id for the element within a resource (for internal references)
1636    pub id: Option<std::string::String>,
1637    /// Additional content defined by implementations
1638    ///
1639    /// May be used to represent additional information that is not part of the
1640    /// basic definition of the resource. To make the use of extensions safe and
1641    /// manageable, there is a strict set of governance applied to the definition
1642    /// and use of extensions. Though any implementer can define an extension, there
1643    /// is a set of requirements that SHALL be met as part of the definition of the
1644    /// extension.
1645    pub extension: Vec<super::extension::Extension>,
1646    /// Primitive value for instant
1647    ///
1648    /// The actual value
1649    pub value: Option<std::string::String>,
1650}
1651impl From<std::string::String> for Instant {
1652    fn from(value: std::string::String) -> Self {
1653        Self {
1654            value: Some(value),
1655            ..Self::default()
1656        }
1657    }
1658}
1659impl From<&str> for Instant {
1660    fn from(value: &str) -> Self {
1661        Self::from(std::string::String::from(value))
1662    }
1663}
1664
1665/// The lexical form of the FHIR primitive `instant`, anchored to the whole value.
1666///
1667/// The `regex` extension of `instant.value` states it (<https://hl7.org/fhir/R4/datatypes.html#primitive>),
1668/// and the form is an XML Schema pattern, where `\s` is the space, the tab,
1669/// the carriage return and the line feed alone (<https://www.w3.org/TR/xmlschema-2/#regexs>).
1670#[expect(
1671    clippy::expect_used,
1672    reason = "the emitter compiles every lexical form it writes, so the pattern holds"
1673)]
1674static INSTANT_LEXICAL_FORM: std::sync::LazyLock<regex::bytes::Regex> = std::sync::LazyLock::new(
1675    || {
1676        regex::bytes::RegexBuilder::new(r"^(?:([0-9]([0-9]([0-9][1-9]|[1-9]0)|[1-9]00)|[1-9]000)-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])T([01][0-9]|2[0-3]):[0-5][0-9]:([0-5][0-9]|60)(\.[0-9]+)?(Z|(\+|-)((0[0-9]|1[0-3]):[0-5][0-9]|14:00)))$")
1677        .unicode(false)
1678        .build()
1679        .expect("the lexical form of `instant` should compile")
1680    },
1681);
1682
1683/// Hands back `text` when it keeps the lexical form of `instant`.
1684///
1685/// # Errors
1686///
1687/// Returns [`super::super::codec::DecodeErrorKind::BadValue`] at `path` for a value outside the form.
1688pub(crate) fn checked_instant(
1689    text: std::string::String,
1690    path: &super::super::codec::Path,
1691) -> Result<std::string::String, super::super::codec::DecodeError> {
1692    if INSTANT_LEXICAL_FORM.is_match(text.as_bytes()) {
1693        Ok(text)
1694    } else {
1695        Err(path.error(super::super::codec::DecodeErrorKind::BadValue))
1696    }
1697}
1698
1699impl Instant {
1700    /// Checks `text` against the lexical form of `instant`, the one the decoder holds a value to.
1701    ///
1702    /// # Errors
1703    ///
1704    /// Returns [`super::super::codec::LexicalError`] naming `instant` when `text` is outside the form.
1705    pub fn check(text: &str) -> Result<(), super::super::codec::LexicalError> {
1706        if INSTANT_LEXICAL_FORM.is_match(text.as_bytes()) {
1707            Ok(())
1708        } else {
1709            Err(super::super::codec::LexicalError {
1710                type_code: "instant",
1711            })
1712        }
1713    }
1714}
1715
1716impl super::super::codec::Primitive for Instant {
1717    fn value_json(
1718        &self,
1719    ) -> Result<Option<super::super::codec::Value>, super::super::codec::EncodeError> {
1720        Ok(self
1721            .value
1722            .as_ref()
1723            .map(|v| super::super::codec::Value::String(v.clone())))
1724    }
1725
1726    fn element_json(
1727        &self,
1728    ) -> Result<Option<super::super::codec::Value>, super::super::codec::EncodeError> {
1729        if self.id.is_none() && self.extension.is_empty() {
1730            return Ok(None);
1731        }
1732        let mut object = super::super::codec::Object::new();
1733        if let Some(id) = &self.id {
1734            object.insert(
1735                std::string::String::from("id"),
1736                super::super::codec::Value::String(id.clone()),
1737            );
1738        }
1739        if !self.extension.is_empty() {
1740            let mut items = Vec::with_capacity(self.extension.len());
1741            for item in &self.extension {
1742                items.push(super::super::codec::Value::Object(
1743                    super::super::codec::Json::to_json(item)?,
1744                ));
1745            }
1746            object.insert(
1747                std::string::String::from("extension"),
1748                super::super::codec::Value::Array(items),
1749            );
1750        }
1751        Ok(Some(super::super::codec::Value::Object(object)))
1752    }
1753
1754    fn has_value(&self) -> bool {
1755        self.value.is_some()
1756    }
1757
1758    fn has_element(&self) -> bool {
1759        self.id.is_some() || !self.extension.is_empty()
1760    }
1761
1762    fn serialize_value<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
1763        match self.value.as_ref() {
1764            Some(v) => serde::Serializer::serialize_str(serializer, v),
1765            None => serde::Serializer::serialize_none(serializer),
1766        }
1767    }
1768
1769    fn serialize_element<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
1770        if self.id.is_none() && self.extension.is_empty() {
1771            return serde::Serializer::serialize_none(serializer);
1772        }
1773        let mut map = serde::Serializer::serialize_map(serializer, None)?;
1774        if !self.extension.is_empty() {
1775            serde::ser::SerializeMap::serialize_entry(&mut map, "extension", &self.extension)?;
1776        }
1777        if let Some(id) = &self.id {
1778            serde::ser::SerializeMap::serialize_entry(&mut map, "id", id)?;
1779        }
1780        serde::ser::SerializeMap::end(map)
1781    }
1782
1783    fn from_json_parts(
1784        value: Option<&super::super::codec::Value>,
1785        element: Option<&super::super::codec::Value>,
1786        path: &mut super::super::codec::Path,
1787    ) -> Result<Self, super::super::codec::DecodeError> {
1788        if value.is_none() && element.is_none() && !path.is_lenient() {
1789            return Err(path.error(super::super::codec::DecodeErrorKind::MissingProperty));
1790        }
1791        let value = match value {
1792            Some(value) => {
1793                let value = super::super::codec::expect_single(value, path)?;
1794                Some(checked_instant(
1795                    super::super::codec::expect_string(value, path)?,
1796                    path,
1797                )?)
1798            }
1799            None => None,
1800        };
1801        let mut id = None;
1802        let mut extension = Vec::new();
1803        if let Some(element) = element {
1804            let object = super::super::codec::expect_object(element, path)?;
1805            for (key, item) in object {
1806                match key.as_str() {
1807                    "id" => {
1808                        id = Some(path.with("id", |path| {
1809                            super::primitives::checked_string(
1810                                super::super::codec::expect_string(item, path)?,
1811                                path,
1812                            )
1813                        })?);
1814                    }
1815                    "extension" => {
1816                        for (index, entry) in super::super::codec::expect_array(item, path)?
1817                            .iter()
1818                            .enumerate()
1819                        {
1820                            extension.push(path.with_index("extension", index, |path| {
1821                                super::super::codec::Json::from_json(
1822                                    super::super::codec::expect_object(entry, path)?,
1823                                    path,
1824                                )
1825                            })?);
1826                        }
1827                    }
1828                    _ => {
1829                        return path.with(key, |path| {
1830                            Err(path.error(super::super::codec::DecodeErrorKind::UnknownProperty))
1831                        });
1832                    }
1833                }
1834            }
1835        }
1836        Ok(Self {
1837            id,
1838            extension,
1839            value,
1840        })
1841    }
1842}
1843
1844/// Primitive Type integer
1845///
1846/// A whole number
1847#[derive(Debug, Clone, Default, PartialEq, Eq)]
1848pub struct Integer {
1849    /// xml:id (or equivalent in JSON)
1850    ///
1851    /// unique id for the element within a resource (for internal references)
1852    pub id: Option<std::string::String>,
1853    /// Additional content defined by implementations
1854    ///
1855    /// May be used to represent additional information that is not part of the
1856    /// basic definition of the resource. To make the use of extensions safe and
1857    /// manageable, there is a strict set of governance applied to the definition
1858    /// and use of extensions. Though any implementer can define an extension, there
1859    /// is a set of requirements that SHALL be met as part of the definition of the
1860    /// extension.
1861    pub extension: Vec<super::extension::Extension>,
1862    /// Primitive value for integer
1863    ///
1864    /// The actual value
1865    pub value: Option<i32>,
1866}
1867impl From<i32> for Integer {
1868    fn from(value: i32) -> Self {
1869        Self {
1870            value: Some(value),
1871            ..Self::default()
1872        }
1873    }
1874}
1875
1876impl super::super::codec::Primitive for Integer {
1877    fn value_json(
1878        &self,
1879    ) -> Result<Option<super::super::codec::Value>, super::super::codec::EncodeError> {
1880        Ok(self
1881            .value
1882            .as_ref()
1883            .map(|v| super::super::codec::Value::from(*v)))
1884    }
1885
1886    fn element_json(
1887        &self,
1888    ) -> Result<Option<super::super::codec::Value>, super::super::codec::EncodeError> {
1889        if self.id.is_none() && self.extension.is_empty() {
1890            return Ok(None);
1891        }
1892        let mut object = super::super::codec::Object::new();
1893        if let Some(id) = &self.id {
1894            object.insert(
1895                std::string::String::from("id"),
1896                super::super::codec::Value::String(id.clone()),
1897            );
1898        }
1899        if !self.extension.is_empty() {
1900            let mut items = Vec::with_capacity(self.extension.len());
1901            for item in &self.extension {
1902                items.push(super::super::codec::Value::Object(
1903                    super::super::codec::Json::to_json(item)?,
1904                ));
1905            }
1906            object.insert(
1907                std::string::String::from("extension"),
1908                super::super::codec::Value::Array(items),
1909            );
1910        }
1911        Ok(Some(super::super::codec::Value::Object(object)))
1912    }
1913
1914    fn has_value(&self) -> bool {
1915        self.value.is_some()
1916    }
1917
1918    fn has_element(&self) -> bool {
1919        self.id.is_some() || !self.extension.is_empty()
1920    }
1921
1922    fn serialize_value<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
1923        match self.value.as_ref() {
1924            Some(v) => serde::Serializer::serialize_i32(serializer, *v),
1925            None => serde::Serializer::serialize_none(serializer),
1926        }
1927    }
1928
1929    fn serialize_element<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
1930        if self.id.is_none() && self.extension.is_empty() {
1931            return serde::Serializer::serialize_none(serializer);
1932        }
1933        let mut map = serde::Serializer::serialize_map(serializer, None)?;
1934        if !self.extension.is_empty() {
1935            serde::ser::SerializeMap::serialize_entry(&mut map, "extension", &self.extension)?;
1936        }
1937        if let Some(id) = &self.id {
1938            serde::ser::SerializeMap::serialize_entry(&mut map, "id", id)?;
1939        }
1940        serde::ser::SerializeMap::end(map)
1941    }
1942
1943    fn from_json_parts(
1944        value: Option<&super::super::codec::Value>,
1945        element: Option<&super::super::codec::Value>,
1946        path: &mut super::super::codec::Path,
1947    ) -> Result<Self, super::super::codec::DecodeError> {
1948        if value.is_none() && element.is_none() && !path.is_lenient() {
1949            return Err(path.error(super::super::codec::DecodeErrorKind::MissingProperty));
1950        }
1951        let value = match value {
1952            Some(value) => {
1953                let value = super::super::codec::expect_single(value, path)?;
1954                Some(super::super::codec::expect_i32(value, path)?)
1955            }
1956            None => None,
1957        };
1958        let mut id = None;
1959        let mut extension = Vec::new();
1960        if let Some(element) = element {
1961            let object = super::super::codec::expect_object(element, path)?;
1962            for (key, item) in object {
1963                match key.as_str() {
1964                    "id" => {
1965                        id = Some(path.with("id", |path| {
1966                            super::primitives::checked_string(
1967                                super::super::codec::expect_string(item, path)?,
1968                                path,
1969                            )
1970                        })?);
1971                    }
1972                    "extension" => {
1973                        for (index, entry) in super::super::codec::expect_array(item, path)?
1974                            .iter()
1975                            .enumerate()
1976                        {
1977                            extension.push(path.with_index("extension", index, |path| {
1978                                super::super::codec::Json::from_json(
1979                                    super::super::codec::expect_object(entry, path)?,
1980                                    path,
1981                                )
1982                            })?);
1983                        }
1984                    }
1985                    _ => {
1986                        return path.with(key, |path| {
1987                            Err(path.error(super::super::codec::DecodeErrorKind::UnknownProperty))
1988                        });
1989                    }
1990                }
1991            }
1992        }
1993        Ok(Self {
1994            id,
1995            extension,
1996            value,
1997        })
1998    }
1999}
2000
2001/// Primitive Type markdown
2002///
2003/// A string that may contain Github Flavored Markdown syntax for optional
2004/// processing by a mark down presentation engine
2005#[derive(Debug, Clone, Default, PartialEq, Eq)]
2006pub struct Markdown {
2007    /// xml:id (or equivalent in JSON)
2008    ///
2009    /// unique id for the element within a resource (for internal references)
2010    pub id: Option<std::string::String>,
2011    /// Additional content defined by implementations
2012    ///
2013    /// May be used to represent additional information that is not part of the
2014    /// basic definition of the resource. To make the use of extensions safe and
2015    /// manageable, there is a strict set of governance applied to the definition
2016    /// and use of extensions. Though any implementer can define an extension, there
2017    /// is a set of requirements that SHALL be met as part of the definition of the
2018    /// extension.
2019    pub extension: Vec<super::extension::Extension>,
2020    /// Primitive value for markdown
2021    pub value: Option<std::string::String>,
2022}
2023impl From<std::string::String> for Markdown {
2024    fn from(value: std::string::String) -> Self {
2025        Self {
2026            value: Some(value),
2027            ..Self::default()
2028        }
2029    }
2030}
2031impl From<&str> for Markdown {
2032    fn from(value: &str) -> Self {
2033        Self::from(std::string::String::from(value))
2034    }
2035}
2036
2037/// The lexical form of the FHIR primitive `markdown`, anchored to the whole value.
2038///
2039/// The `regex` extension of `markdown.value` states it (<https://hl7.org/fhir/R4/datatypes.html#primitive>),
2040/// and the form is an XML Schema pattern, where `\s` is the space, the tab,
2041/// the carriage return and the line feed alone (<https://www.w3.org/TR/xmlschema-2/#regexs>).
2042#[expect(
2043    clippy::expect_used,
2044    reason = "the emitter compiles every lexical form it writes, so the pattern holds"
2045)]
2046static MARKDOWN_LEXICAL_FORM: std::sync::LazyLock<regex::bytes::Regex> =
2047    std::sync::LazyLock::new(|| {
2048        regex::bytes::RegexBuilder::new(r"^(?:[ \r\n\t\S]+)$")
2049            .unicode(false)
2050            .build()
2051            .expect("the lexical form of `markdown` should compile")
2052    });
2053
2054/// Hands back `text` when it keeps the lexical form of `markdown`.
2055///
2056/// # Errors
2057///
2058/// Returns [`super::super::codec::DecodeErrorKind::BadValue`] at `path` for a value outside the form.
2059pub(crate) fn checked_markdown(
2060    text: std::string::String,
2061    path: &super::super::codec::Path,
2062) -> Result<std::string::String, super::super::codec::DecodeError> {
2063    if MARKDOWN_LEXICAL_FORM.is_match(text.as_bytes()) {
2064        Ok(text)
2065    } else {
2066        Err(path.error(super::super::codec::DecodeErrorKind::BadValue))
2067    }
2068}
2069
2070impl Markdown {
2071    /// Checks `text` against the lexical form of `markdown`, the one the decoder holds a value to.
2072    ///
2073    /// # Errors
2074    ///
2075    /// Returns [`super::super::codec::LexicalError`] naming `markdown` when `text` is outside the form.
2076    pub fn check(text: &str) -> Result<(), super::super::codec::LexicalError> {
2077        if MARKDOWN_LEXICAL_FORM.is_match(text.as_bytes()) {
2078            Ok(())
2079        } else {
2080            Err(super::super::codec::LexicalError {
2081                type_code: "markdown",
2082            })
2083        }
2084    }
2085}
2086
2087impl super::super::codec::Primitive for Markdown {
2088    fn value_json(
2089        &self,
2090    ) -> Result<Option<super::super::codec::Value>, super::super::codec::EncodeError> {
2091        Ok(self
2092            .value
2093            .as_ref()
2094            .map(|v| super::super::codec::Value::String(v.clone())))
2095    }
2096
2097    fn element_json(
2098        &self,
2099    ) -> Result<Option<super::super::codec::Value>, super::super::codec::EncodeError> {
2100        if self.id.is_none() && self.extension.is_empty() {
2101            return Ok(None);
2102        }
2103        let mut object = super::super::codec::Object::new();
2104        if let Some(id) = &self.id {
2105            object.insert(
2106                std::string::String::from("id"),
2107                super::super::codec::Value::String(id.clone()),
2108            );
2109        }
2110        if !self.extension.is_empty() {
2111            let mut items = Vec::with_capacity(self.extension.len());
2112            for item in &self.extension {
2113                items.push(super::super::codec::Value::Object(
2114                    super::super::codec::Json::to_json(item)?,
2115                ));
2116            }
2117            object.insert(
2118                std::string::String::from("extension"),
2119                super::super::codec::Value::Array(items),
2120            );
2121        }
2122        Ok(Some(super::super::codec::Value::Object(object)))
2123    }
2124
2125    fn has_value(&self) -> bool {
2126        self.value.is_some()
2127    }
2128
2129    fn has_element(&self) -> bool {
2130        self.id.is_some() || !self.extension.is_empty()
2131    }
2132
2133    fn serialize_value<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
2134        match self.value.as_ref() {
2135            Some(v) => serde::Serializer::serialize_str(serializer, v),
2136            None => serde::Serializer::serialize_none(serializer),
2137        }
2138    }
2139
2140    fn serialize_element<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
2141        if self.id.is_none() && self.extension.is_empty() {
2142            return serde::Serializer::serialize_none(serializer);
2143        }
2144        let mut map = serde::Serializer::serialize_map(serializer, None)?;
2145        if !self.extension.is_empty() {
2146            serde::ser::SerializeMap::serialize_entry(&mut map, "extension", &self.extension)?;
2147        }
2148        if let Some(id) = &self.id {
2149            serde::ser::SerializeMap::serialize_entry(&mut map, "id", id)?;
2150        }
2151        serde::ser::SerializeMap::end(map)
2152    }
2153
2154    fn from_json_parts(
2155        value: Option<&super::super::codec::Value>,
2156        element: Option<&super::super::codec::Value>,
2157        path: &mut super::super::codec::Path,
2158    ) -> Result<Self, super::super::codec::DecodeError> {
2159        if value.is_none() && element.is_none() && !path.is_lenient() {
2160            return Err(path.error(super::super::codec::DecodeErrorKind::MissingProperty));
2161        }
2162        let value = match value {
2163            Some(value) => {
2164                let value = super::super::codec::expect_single(value, path)?;
2165                Some(checked_markdown(
2166                    super::super::codec::expect_string(value, path)?,
2167                    path,
2168                )?)
2169            }
2170            None => None,
2171        };
2172        let mut id = None;
2173        let mut extension = Vec::new();
2174        if let Some(element) = element {
2175            let object = super::super::codec::expect_object(element, path)?;
2176            for (key, item) in object {
2177                match key.as_str() {
2178                    "id" => {
2179                        id = Some(path.with("id", |path| {
2180                            super::primitives::checked_string(
2181                                super::super::codec::expect_string(item, path)?,
2182                                path,
2183                            )
2184                        })?);
2185                    }
2186                    "extension" => {
2187                        for (index, entry) in super::super::codec::expect_array(item, path)?
2188                            .iter()
2189                            .enumerate()
2190                        {
2191                            extension.push(path.with_index("extension", index, |path| {
2192                                super::super::codec::Json::from_json(
2193                                    super::super::codec::expect_object(entry, path)?,
2194                                    path,
2195                                )
2196                            })?);
2197                        }
2198                    }
2199                    _ => {
2200                        return path.with(key, |path| {
2201                            Err(path.error(super::super::codec::DecodeErrorKind::UnknownProperty))
2202                        });
2203                    }
2204                }
2205            }
2206        }
2207        Ok(Self {
2208            id,
2209            extension,
2210            value,
2211        })
2212    }
2213}
2214
2215/// Primitive Type oid
2216///
2217/// An OID represented as a URI
2218#[derive(Debug, Clone, Default, PartialEq, Eq)]
2219pub struct Oid {
2220    /// xml:id (or equivalent in JSON)
2221    ///
2222    /// unique id for the element within a resource (for internal references)
2223    pub id: Option<std::string::String>,
2224    /// Additional content defined by implementations
2225    ///
2226    /// May be used to represent additional information that is not part of the
2227    /// basic definition of the resource. To make the use of extensions safe and
2228    /// manageable, there is a strict set of governance applied to the definition
2229    /// and use of extensions. Though any implementer can define an extension, there
2230    /// is a set of requirements that SHALL be met as part of the definition of the
2231    /// extension.
2232    pub extension: Vec<super::extension::Extension>,
2233    /// Primitive value for oid
2234    pub value: Option<std::string::String>,
2235}
2236impl From<std::string::String> for Oid {
2237    fn from(value: std::string::String) -> Self {
2238        Self {
2239            value: Some(value),
2240            ..Self::default()
2241        }
2242    }
2243}
2244impl From<&str> for Oid {
2245    fn from(value: &str) -> Self {
2246        Self::from(std::string::String::from(value))
2247    }
2248}
2249
2250/// The lexical form of the FHIR primitive `oid`, anchored to the whole value.
2251///
2252/// The `regex` extension of `oid.value` states it (<https://hl7.org/fhir/R4/datatypes.html#primitive>),
2253/// and the form is an XML Schema pattern, where `\s` is the space, the tab,
2254/// the carriage return and the line feed alone (<https://www.w3.org/TR/xmlschema-2/#regexs>).
2255#[expect(
2256    clippy::expect_used,
2257    reason = "the emitter compiles every lexical form it writes, so the pattern holds"
2258)]
2259static OID_LEXICAL_FORM: std::sync::LazyLock<regex::bytes::Regex> =
2260    std::sync::LazyLock::new(|| {
2261        regex::bytes::RegexBuilder::new(r"^(?:urn:oid:[0-2](\.(0|[1-9][0-9]*))+)$")
2262            .unicode(false)
2263            .build()
2264            .expect("the lexical form of `oid` should compile")
2265    });
2266
2267/// Hands back `text` when it keeps the lexical form of `oid`.
2268///
2269/// # Errors
2270///
2271/// Returns [`super::super::codec::DecodeErrorKind::BadValue`] at `path` for a value outside the form.
2272pub(crate) fn checked_oid(
2273    text: std::string::String,
2274    path: &super::super::codec::Path,
2275) -> Result<std::string::String, super::super::codec::DecodeError> {
2276    if OID_LEXICAL_FORM.is_match(text.as_bytes()) {
2277        Ok(text)
2278    } else {
2279        Err(path.error(super::super::codec::DecodeErrorKind::BadValue))
2280    }
2281}
2282
2283impl Oid {
2284    /// Checks `text` against the lexical form of `oid`, the one the decoder holds a value to.
2285    ///
2286    /// # Errors
2287    ///
2288    /// Returns [`super::super::codec::LexicalError`] naming `oid` when `text` is outside the form.
2289    pub fn check(text: &str) -> Result<(), super::super::codec::LexicalError> {
2290        if OID_LEXICAL_FORM.is_match(text.as_bytes()) {
2291            Ok(())
2292        } else {
2293            Err(super::super::codec::LexicalError { type_code: "oid" })
2294        }
2295    }
2296}
2297
2298impl super::super::codec::Primitive for Oid {
2299    fn value_json(
2300        &self,
2301    ) -> Result<Option<super::super::codec::Value>, super::super::codec::EncodeError> {
2302        Ok(self
2303            .value
2304            .as_ref()
2305            .map(|v| super::super::codec::Value::String(v.clone())))
2306    }
2307
2308    fn element_json(
2309        &self,
2310    ) -> Result<Option<super::super::codec::Value>, super::super::codec::EncodeError> {
2311        if self.id.is_none() && self.extension.is_empty() {
2312            return Ok(None);
2313        }
2314        let mut object = super::super::codec::Object::new();
2315        if let Some(id) = &self.id {
2316            object.insert(
2317                std::string::String::from("id"),
2318                super::super::codec::Value::String(id.clone()),
2319            );
2320        }
2321        if !self.extension.is_empty() {
2322            let mut items = Vec::with_capacity(self.extension.len());
2323            for item in &self.extension {
2324                items.push(super::super::codec::Value::Object(
2325                    super::super::codec::Json::to_json(item)?,
2326                ));
2327            }
2328            object.insert(
2329                std::string::String::from("extension"),
2330                super::super::codec::Value::Array(items),
2331            );
2332        }
2333        Ok(Some(super::super::codec::Value::Object(object)))
2334    }
2335
2336    fn has_value(&self) -> bool {
2337        self.value.is_some()
2338    }
2339
2340    fn has_element(&self) -> bool {
2341        self.id.is_some() || !self.extension.is_empty()
2342    }
2343
2344    fn serialize_value<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
2345        match self.value.as_ref() {
2346            Some(v) => serde::Serializer::serialize_str(serializer, v),
2347            None => serde::Serializer::serialize_none(serializer),
2348        }
2349    }
2350
2351    fn serialize_element<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
2352        if self.id.is_none() && self.extension.is_empty() {
2353            return serde::Serializer::serialize_none(serializer);
2354        }
2355        let mut map = serde::Serializer::serialize_map(serializer, None)?;
2356        if !self.extension.is_empty() {
2357            serde::ser::SerializeMap::serialize_entry(&mut map, "extension", &self.extension)?;
2358        }
2359        if let Some(id) = &self.id {
2360            serde::ser::SerializeMap::serialize_entry(&mut map, "id", id)?;
2361        }
2362        serde::ser::SerializeMap::end(map)
2363    }
2364
2365    fn from_json_parts(
2366        value: Option<&super::super::codec::Value>,
2367        element: Option<&super::super::codec::Value>,
2368        path: &mut super::super::codec::Path,
2369    ) -> Result<Self, super::super::codec::DecodeError> {
2370        if value.is_none() && element.is_none() && !path.is_lenient() {
2371            return Err(path.error(super::super::codec::DecodeErrorKind::MissingProperty));
2372        }
2373        let value = match value {
2374            Some(value) => {
2375                let value = super::super::codec::expect_single(value, path)?;
2376                Some(checked_oid(
2377                    super::super::codec::expect_string(value, path)?,
2378                    path,
2379                )?)
2380            }
2381            None => None,
2382        };
2383        let mut id = None;
2384        let mut extension = Vec::new();
2385        if let Some(element) = element {
2386            let object = super::super::codec::expect_object(element, path)?;
2387            for (key, item) in object {
2388                match key.as_str() {
2389                    "id" => {
2390                        id = Some(path.with("id", |path| {
2391                            super::primitives::checked_string(
2392                                super::super::codec::expect_string(item, path)?,
2393                                path,
2394                            )
2395                        })?);
2396                    }
2397                    "extension" => {
2398                        for (index, entry) in super::super::codec::expect_array(item, path)?
2399                            .iter()
2400                            .enumerate()
2401                        {
2402                            extension.push(path.with_index("extension", index, |path| {
2403                                super::super::codec::Json::from_json(
2404                                    super::super::codec::expect_object(entry, path)?,
2405                                    path,
2406                                )
2407                            })?);
2408                        }
2409                    }
2410                    _ => {
2411                        return path.with(key, |path| {
2412                            Err(path.error(super::super::codec::DecodeErrorKind::UnknownProperty))
2413                        });
2414                    }
2415                }
2416            }
2417        }
2418        Ok(Self {
2419            id,
2420            extension,
2421            value,
2422        })
2423    }
2424}
2425
2426/// Primitive Type positiveInt
2427///
2428/// An integer with a value that is positive (e.g. \>0)
2429#[derive(Debug, Clone, Default, PartialEq, Eq)]
2430pub struct PositiveInt {
2431    /// xml:id (or equivalent in JSON)
2432    ///
2433    /// unique id for the element within a resource (for internal references)
2434    pub id: Option<std::string::String>,
2435    /// Additional content defined by implementations
2436    ///
2437    /// May be used to represent additional information that is not part of the
2438    /// basic definition of the resource. To make the use of extensions safe and
2439    /// manageable, there is a strict set of governance applied to the definition
2440    /// and use of extensions. Though any implementer can define an extension, there
2441    /// is a set of requirements that SHALL be met as part of the definition of the
2442    /// extension.
2443    pub extension: Vec<super::extension::Extension>,
2444    /// Primitive value for positiveInt
2445    pub value: Option<u32>,
2446}
2447impl From<u32> for PositiveInt {
2448    fn from(value: u32) -> Self {
2449        Self {
2450            value: Some(value),
2451            ..Self::default()
2452        }
2453    }
2454}
2455
2456impl super::super::codec::Primitive for PositiveInt {
2457    fn value_json(
2458        &self,
2459    ) -> Result<Option<super::super::codec::Value>, super::super::codec::EncodeError> {
2460        Ok(self
2461            .value
2462            .as_ref()
2463            .map(|v| super::super::codec::Value::from(*v)))
2464    }
2465
2466    fn element_json(
2467        &self,
2468    ) -> Result<Option<super::super::codec::Value>, super::super::codec::EncodeError> {
2469        if self.id.is_none() && self.extension.is_empty() {
2470            return Ok(None);
2471        }
2472        let mut object = super::super::codec::Object::new();
2473        if let Some(id) = &self.id {
2474            object.insert(
2475                std::string::String::from("id"),
2476                super::super::codec::Value::String(id.clone()),
2477            );
2478        }
2479        if !self.extension.is_empty() {
2480            let mut items = Vec::with_capacity(self.extension.len());
2481            for item in &self.extension {
2482                items.push(super::super::codec::Value::Object(
2483                    super::super::codec::Json::to_json(item)?,
2484                ));
2485            }
2486            object.insert(
2487                std::string::String::from("extension"),
2488                super::super::codec::Value::Array(items),
2489            );
2490        }
2491        Ok(Some(super::super::codec::Value::Object(object)))
2492    }
2493
2494    fn has_value(&self) -> bool {
2495        self.value.is_some()
2496    }
2497
2498    fn has_element(&self) -> bool {
2499        self.id.is_some() || !self.extension.is_empty()
2500    }
2501
2502    fn serialize_value<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
2503        match self.value.as_ref() {
2504            Some(v) => serde::Serializer::serialize_u32(serializer, *v),
2505            None => serde::Serializer::serialize_none(serializer),
2506        }
2507    }
2508
2509    fn serialize_element<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
2510        if self.id.is_none() && self.extension.is_empty() {
2511            return serde::Serializer::serialize_none(serializer);
2512        }
2513        let mut map = serde::Serializer::serialize_map(serializer, None)?;
2514        if !self.extension.is_empty() {
2515            serde::ser::SerializeMap::serialize_entry(&mut map, "extension", &self.extension)?;
2516        }
2517        if let Some(id) = &self.id {
2518            serde::ser::SerializeMap::serialize_entry(&mut map, "id", id)?;
2519        }
2520        serde::ser::SerializeMap::end(map)
2521    }
2522
2523    fn from_json_parts(
2524        value: Option<&super::super::codec::Value>,
2525        element: Option<&super::super::codec::Value>,
2526        path: &mut super::super::codec::Path,
2527    ) -> Result<Self, super::super::codec::DecodeError> {
2528        if value.is_none() && element.is_none() && !path.is_lenient() {
2529            return Err(path.error(super::super::codec::DecodeErrorKind::MissingProperty));
2530        }
2531        let value = match value {
2532            Some(value) => {
2533                let value = super::super::codec::expect_single(value, path)?;
2534                Some(super::super::codec::expect_u32(value, 1, path)?)
2535            }
2536            None => None,
2537        };
2538        let mut id = None;
2539        let mut extension = Vec::new();
2540        if let Some(element) = element {
2541            let object = super::super::codec::expect_object(element, path)?;
2542            for (key, item) in object {
2543                match key.as_str() {
2544                    "id" => {
2545                        id = Some(path.with("id", |path| {
2546                            super::primitives::checked_string(
2547                                super::super::codec::expect_string(item, path)?,
2548                                path,
2549                            )
2550                        })?);
2551                    }
2552                    "extension" => {
2553                        for (index, entry) in super::super::codec::expect_array(item, path)?
2554                            .iter()
2555                            .enumerate()
2556                        {
2557                            extension.push(path.with_index("extension", index, |path| {
2558                                super::super::codec::Json::from_json(
2559                                    super::super::codec::expect_object(entry, path)?,
2560                                    path,
2561                                )
2562                            })?);
2563                        }
2564                    }
2565                    _ => {
2566                        return path.with(key, |path| {
2567                            Err(path.error(super::super::codec::DecodeErrorKind::UnknownProperty))
2568                        });
2569                    }
2570                }
2571            }
2572        }
2573        Ok(Self {
2574            id,
2575            extension,
2576            value,
2577        })
2578    }
2579}
2580
2581/// Primitive Type string
2582///
2583/// A sequence of Unicode characters
2584#[derive(Debug, Clone, Default, PartialEq, Eq)]
2585pub struct String {
2586    /// xml:id (or equivalent in JSON)
2587    ///
2588    /// unique id for the element within a resource (for internal references)
2589    pub id: Option<std::string::String>,
2590    /// Additional content defined by implementations
2591    ///
2592    /// May be used to represent additional information that is not part of the
2593    /// basic definition of the resource. To make the use of extensions safe and
2594    /// manageable, there is a strict set of governance applied to the definition
2595    /// and use of extensions. Though any implementer can define an extension, there
2596    /// is a set of requirements that SHALL be met as part of the definition of the
2597    /// extension.
2598    pub extension: Vec<super::extension::Extension>,
2599    /// Primitive value for string
2600    ///
2601    /// The actual value
2602    pub value: Option<std::string::String>,
2603}
2604impl From<std::string::String> for String {
2605    fn from(value: std::string::String) -> Self {
2606        Self {
2607            value: Some(value),
2608            ..Self::default()
2609        }
2610    }
2611}
2612impl From<&str> for String {
2613    fn from(value: &str) -> Self {
2614        Self::from(std::string::String::from(value))
2615    }
2616}
2617
2618/// The lexical form of the FHIR primitive `string`, anchored to the whole value.
2619///
2620/// The `regex` extension of `string.value` states it (<https://hl7.org/fhir/R4/datatypes.html#primitive>),
2621/// and the form is an XML Schema pattern, where `\s` is the space, the tab,
2622/// the carriage return and the line feed alone (<https://www.w3.org/TR/xmlschema-2/#regexs>).
2623#[expect(
2624    clippy::expect_used,
2625    reason = "the emitter compiles every lexical form it writes, so the pattern holds"
2626)]
2627static STRING_LEXICAL_FORM: std::sync::LazyLock<regex::bytes::Regex> =
2628    std::sync::LazyLock::new(|| {
2629        regex::bytes::RegexBuilder::new(r"^(?:[ \r\n\t\S]+)$")
2630            .unicode(false)
2631            .build()
2632            .expect("the lexical form of `string` should compile")
2633    });
2634
2635/// Hands back `text` when it keeps the lexical form of `string`.
2636///
2637/// # Errors
2638///
2639/// Returns [`super::super::codec::DecodeErrorKind::BadValue`] at `path` for a value outside the form.
2640pub(crate) fn checked_string(
2641    text: std::string::String,
2642    path: &super::super::codec::Path,
2643) -> Result<std::string::String, super::super::codec::DecodeError> {
2644    if STRING_LEXICAL_FORM.is_match(text.as_bytes()) {
2645        Ok(text)
2646    } else {
2647        Err(path.error(super::super::codec::DecodeErrorKind::BadValue))
2648    }
2649}
2650
2651impl String {
2652    /// Checks `text` against the lexical form of `string`, the one the decoder holds a value to.
2653    ///
2654    /// # Errors
2655    ///
2656    /// Returns [`super::super::codec::LexicalError`] naming `string` when `text` is outside the form.
2657    pub fn check(text: &str) -> Result<(), super::super::codec::LexicalError> {
2658        if STRING_LEXICAL_FORM.is_match(text.as_bytes()) {
2659            Ok(())
2660        } else {
2661            Err(super::super::codec::LexicalError {
2662                type_code: "string",
2663            })
2664        }
2665    }
2666}
2667
2668impl super::super::codec::Primitive for String {
2669    fn value_json(
2670        &self,
2671    ) -> Result<Option<super::super::codec::Value>, super::super::codec::EncodeError> {
2672        Ok(self
2673            .value
2674            .as_ref()
2675            .map(|v| super::super::codec::Value::String(v.clone())))
2676    }
2677
2678    fn element_json(
2679        &self,
2680    ) -> Result<Option<super::super::codec::Value>, super::super::codec::EncodeError> {
2681        if self.id.is_none() && self.extension.is_empty() {
2682            return Ok(None);
2683        }
2684        let mut object = super::super::codec::Object::new();
2685        if let Some(id) = &self.id {
2686            object.insert(
2687                std::string::String::from("id"),
2688                super::super::codec::Value::String(id.clone()),
2689            );
2690        }
2691        if !self.extension.is_empty() {
2692            let mut items = Vec::with_capacity(self.extension.len());
2693            for item in &self.extension {
2694                items.push(super::super::codec::Value::Object(
2695                    super::super::codec::Json::to_json(item)?,
2696                ));
2697            }
2698            object.insert(
2699                std::string::String::from("extension"),
2700                super::super::codec::Value::Array(items),
2701            );
2702        }
2703        Ok(Some(super::super::codec::Value::Object(object)))
2704    }
2705
2706    fn has_value(&self) -> bool {
2707        self.value.is_some()
2708    }
2709
2710    fn has_element(&self) -> bool {
2711        self.id.is_some() || !self.extension.is_empty()
2712    }
2713
2714    fn serialize_value<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
2715        match self.value.as_ref() {
2716            Some(v) => serde::Serializer::serialize_str(serializer, v),
2717            None => serde::Serializer::serialize_none(serializer),
2718        }
2719    }
2720
2721    fn serialize_element<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
2722        if self.id.is_none() && self.extension.is_empty() {
2723            return serde::Serializer::serialize_none(serializer);
2724        }
2725        let mut map = serde::Serializer::serialize_map(serializer, None)?;
2726        if !self.extension.is_empty() {
2727            serde::ser::SerializeMap::serialize_entry(&mut map, "extension", &self.extension)?;
2728        }
2729        if let Some(id) = &self.id {
2730            serde::ser::SerializeMap::serialize_entry(&mut map, "id", id)?;
2731        }
2732        serde::ser::SerializeMap::end(map)
2733    }
2734
2735    fn from_json_parts(
2736        value: Option<&super::super::codec::Value>,
2737        element: Option<&super::super::codec::Value>,
2738        path: &mut super::super::codec::Path,
2739    ) -> Result<Self, super::super::codec::DecodeError> {
2740        if value.is_none() && element.is_none() && !path.is_lenient() {
2741            return Err(path.error(super::super::codec::DecodeErrorKind::MissingProperty));
2742        }
2743        let value = match value {
2744            Some(value) => {
2745                let value = super::super::codec::expect_single(value, path)?;
2746                Some(checked_string(
2747                    super::super::codec::expect_string(value, path)?,
2748                    path,
2749                )?)
2750            }
2751            None => None,
2752        };
2753        let mut id = None;
2754        let mut extension = Vec::new();
2755        if let Some(element) = element {
2756            let object = super::super::codec::expect_object(element, path)?;
2757            for (key, item) in object {
2758                match key.as_str() {
2759                    "id" => {
2760                        id = Some(path.with("id", |path| {
2761                            super::primitives::checked_string(
2762                                super::super::codec::expect_string(item, path)?,
2763                                path,
2764                            )
2765                        })?);
2766                    }
2767                    "extension" => {
2768                        for (index, entry) in super::super::codec::expect_array(item, path)?
2769                            .iter()
2770                            .enumerate()
2771                        {
2772                            extension.push(path.with_index("extension", index, |path| {
2773                                super::super::codec::Json::from_json(
2774                                    super::super::codec::expect_object(entry, path)?,
2775                                    path,
2776                                )
2777                            })?);
2778                        }
2779                    }
2780                    _ => {
2781                        return path.with(key, |path| {
2782                            Err(path.error(super::super::codec::DecodeErrorKind::UnknownProperty))
2783                        });
2784                    }
2785                }
2786            }
2787        }
2788        Ok(Self {
2789            id,
2790            extension,
2791            value,
2792        })
2793    }
2794}
2795
2796/// Primitive Type time
2797///
2798/// A time during the day, with no date specified
2799#[derive(Debug, Clone, Default, PartialEq, Eq)]
2800pub struct Time {
2801    /// xml:id (or equivalent in JSON)
2802    ///
2803    /// unique id for the element within a resource (for internal references)
2804    pub id: Option<std::string::String>,
2805    /// Additional content defined by implementations
2806    ///
2807    /// May be used to represent additional information that is not part of the
2808    /// basic definition of the resource. To make the use of extensions safe and
2809    /// manageable, there is a strict set of governance applied to the definition
2810    /// and use of extensions. Though any implementer can define an extension, there
2811    /// is a set of requirements that SHALL be met as part of the definition of the
2812    /// extension.
2813    pub extension: Vec<super::extension::Extension>,
2814    /// Primitive value for time
2815    ///
2816    /// The actual value
2817    pub value: Option<std::string::String>,
2818}
2819impl From<std::string::String> for Time {
2820    fn from(value: std::string::String) -> Self {
2821        Self {
2822            value: Some(value),
2823            ..Self::default()
2824        }
2825    }
2826}
2827impl From<&str> for Time {
2828    fn from(value: &str) -> Self {
2829        Self::from(std::string::String::from(value))
2830    }
2831}
2832
2833/// The lexical form of the FHIR primitive `time`, anchored to the whole value.
2834///
2835/// The `regex` extension of `time.value` states it (<https://hl7.org/fhir/R4/datatypes.html#primitive>),
2836/// and the form is an XML Schema pattern, where `\s` is the space, the tab,
2837/// the carriage return and the line feed alone (<https://www.w3.org/TR/xmlschema-2/#regexs>).
2838#[expect(
2839    clippy::expect_used,
2840    reason = "the emitter compiles every lexical form it writes, so the pattern holds"
2841)]
2842static TIME_LEXICAL_FORM: std::sync::LazyLock<regex::bytes::Regex> =
2843    std::sync::LazyLock::new(|| {
2844        regex::bytes::RegexBuilder::new(
2845            r"^(?:([01][0-9]|2[0-3]):[0-5][0-9]:([0-5][0-9]|60)(\.[0-9]+)?)$",
2846        )
2847        .unicode(false)
2848        .build()
2849        .expect("the lexical form of `time` should compile")
2850    });
2851
2852/// Hands back `text` when it keeps the lexical form of `time`.
2853///
2854/// # Errors
2855///
2856/// Returns [`super::super::codec::DecodeErrorKind::BadValue`] at `path` for a value outside the form.
2857pub(crate) fn checked_time(
2858    text: std::string::String,
2859    path: &super::super::codec::Path,
2860) -> Result<std::string::String, super::super::codec::DecodeError> {
2861    if TIME_LEXICAL_FORM.is_match(text.as_bytes()) {
2862        Ok(text)
2863    } else {
2864        Err(path.error(super::super::codec::DecodeErrorKind::BadValue))
2865    }
2866}
2867
2868impl Time {
2869    /// Checks `text` against the lexical form of `time`, the one the decoder holds a value to.
2870    ///
2871    /// # Errors
2872    ///
2873    /// Returns [`super::super::codec::LexicalError`] naming `time` when `text` is outside the form.
2874    pub fn check(text: &str) -> Result<(), super::super::codec::LexicalError> {
2875        if TIME_LEXICAL_FORM.is_match(text.as_bytes()) {
2876            Ok(())
2877        } else {
2878            Err(super::super::codec::LexicalError { type_code: "time" })
2879        }
2880    }
2881}
2882
2883impl super::super::codec::Primitive for Time {
2884    fn value_json(
2885        &self,
2886    ) -> Result<Option<super::super::codec::Value>, super::super::codec::EncodeError> {
2887        Ok(self
2888            .value
2889            .as_ref()
2890            .map(|v| super::super::codec::Value::String(v.clone())))
2891    }
2892
2893    fn element_json(
2894        &self,
2895    ) -> Result<Option<super::super::codec::Value>, super::super::codec::EncodeError> {
2896        if self.id.is_none() && self.extension.is_empty() {
2897            return Ok(None);
2898        }
2899        let mut object = super::super::codec::Object::new();
2900        if let Some(id) = &self.id {
2901            object.insert(
2902                std::string::String::from("id"),
2903                super::super::codec::Value::String(id.clone()),
2904            );
2905        }
2906        if !self.extension.is_empty() {
2907            let mut items = Vec::with_capacity(self.extension.len());
2908            for item in &self.extension {
2909                items.push(super::super::codec::Value::Object(
2910                    super::super::codec::Json::to_json(item)?,
2911                ));
2912            }
2913            object.insert(
2914                std::string::String::from("extension"),
2915                super::super::codec::Value::Array(items),
2916            );
2917        }
2918        Ok(Some(super::super::codec::Value::Object(object)))
2919    }
2920
2921    fn has_value(&self) -> bool {
2922        self.value.is_some()
2923    }
2924
2925    fn has_element(&self) -> bool {
2926        self.id.is_some() || !self.extension.is_empty()
2927    }
2928
2929    fn serialize_value<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
2930        match self.value.as_ref() {
2931            Some(v) => serde::Serializer::serialize_str(serializer, v),
2932            None => serde::Serializer::serialize_none(serializer),
2933        }
2934    }
2935
2936    fn serialize_element<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
2937        if self.id.is_none() && self.extension.is_empty() {
2938            return serde::Serializer::serialize_none(serializer);
2939        }
2940        let mut map = serde::Serializer::serialize_map(serializer, None)?;
2941        if !self.extension.is_empty() {
2942            serde::ser::SerializeMap::serialize_entry(&mut map, "extension", &self.extension)?;
2943        }
2944        if let Some(id) = &self.id {
2945            serde::ser::SerializeMap::serialize_entry(&mut map, "id", id)?;
2946        }
2947        serde::ser::SerializeMap::end(map)
2948    }
2949
2950    fn from_json_parts(
2951        value: Option<&super::super::codec::Value>,
2952        element: Option<&super::super::codec::Value>,
2953        path: &mut super::super::codec::Path,
2954    ) -> Result<Self, super::super::codec::DecodeError> {
2955        if value.is_none() && element.is_none() && !path.is_lenient() {
2956            return Err(path.error(super::super::codec::DecodeErrorKind::MissingProperty));
2957        }
2958        let value = match value {
2959            Some(value) => {
2960                let value = super::super::codec::expect_single(value, path)?;
2961                Some(checked_time(
2962                    super::super::codec::expect_string(value, path)?,
2963                    path,
2964                )?)
2965            }
2966            None => None,
2967        };
2968        let mut id = None;
2969        let mut extension = Vec::new();
2970        if let Some(element) = element {
2971            let object = super::super::codec::expect_object(element, path)?;
2972            for (key, item) in object {
2973                match key.as_str() {
2974                    "id" => {
2975                        id = Some(path.with("id", |path| {
2976                            super::primitives::checked_string(
2977                                super::super::codec::expect_string(item, path)?,
2978                                path,
2979                            )
2980                        })?);
2981                    }
2982                    "extension" => {
2983                        for (index, entry) in super::super::codec::expect_array(item, path)?
2984                            .iter()
2985                            .enumerate()
2986                        {
2987                            extension.push(path.with_index("extension", index, |path| {
2988                                super::super::codec::Json::from_json(
2989                                    super::super::codec::expect_object(entry, path)?,
2990                                    path,
2991                                )
2992                            })?);
2993                        }
2994                    }
2995                    _ => {
2996                        return path.with(key, |path| {
2997                            Err(path.error(super::super::codec::DecodeErrorKind::UnknownProperty))
2998                        });
2999                    }
3000                }
3001            }
3002        }
3003        Ok(Self {
3004            id,
3005            extension,
3006            value,
3007        })
3008    }
3009}
3010
3011/// Primitive Type unsignedInt
3012///
3013/// An integer with a value that is not negative (e.g. \>= 0)
3014#[derive(Debug, Clone, Default, PartialEq, Eq)]
3015pub struct UnsignedInt {
3016    /// xml:id (or equivalent in JSON)
3017    ///
3018    /// unique id for the element within a resource (for internal references)
3019    pub id: Option<std::string::String>,
3020    /// Additional content defined by implementations
3021    ///
3022    /// May be used to represent additional information that is not part of the
3023    /// basic definition of the resource. To make the use of extensions safe and
3024    /// manageable, there is a strict set of governance applied to the definition
3025    /// and use of extensions. Though any implementer can define an extension, there
3026    /// is a set of requirements that SHALL be met as part of the definition of the
3027    /// extension.
3028    pub extension: Vec<super::extension::Extension>,
3029    /// Primitive value for unsignedInt
3030    pub value: Option<u32>,
3031}
3032impl From<u32> for UnsignedInt {
3033    fn from(value: u32) -> Self {
3034        Self {
3035            value: Some(value),
3036            ..Self::default()
3037        }
3038    }
3039}
3040
3041impl super::super::codec::Primitive for UnsignedInt {
3042    fn value_json(
3043        &self,
3044    ) -> Result<Option<super::super::codec::Value>, super::super::codec::EncodeError> {
3045        Ok(self
3046            .value
3047            .as_ref()
3048            .map(|v| super::super::codec::Value::from(*v)))
3049    }
3050
3051    fn element_json(
3052        &self,
3053    ) -> Result<Option<super::super::codec::Value>, super::super::codec::EncodeError> {
3054        if self.id.is_none() && self.extension.is_empty() {
3055            return Ok(None);
3056        }
3057        let mut object = super::super::codec::Object::new();
3058        if let Some(id) = &self.id {
3059            object.insert(
3060                std::string::String::from("id"),
3061                super::super::codec::Value::String(id.clone()),
3062            );
3063        }
3064        if !self.extension.is_empty() {
3065            let mut items = Vec::with_capacity(self.extension.len());
3066            for item in &self.extension {
3067                items.push(super::super::codec::Value::Object(
3068                    super::super::codec::Json::to_json(item)?,
3069                ));
3070            }
3071            object.insert(
3072                std::string::String::from("extension"),
3073                super::super::codec::Value::Array(items),
3074            );
3075        }
3076        Ok(Some(super::super::codec::Value::Object(object)))
3077    }
3078
3079    fn has_value(&self) -> bool {
3080        self.value.is_some()
3081    }
3082
3083    fn has_element(&self) -> bool {
3084        self.id.is_some() || !self.extension.is_empty()
3085    }
3086
3087    fn serialize_value<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
3088        match self.value.as_ref() {
3089            Some(v) => serde::Serializer::serialize_u32(serializer, *v),
3090            None => serde::Serializer::serialize_none(serializer),
3091        }
3092    }
3093
3094    fn serialize_element<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
3095        if self.id.is_none() && self.extension.is_empty() {
3096            return serde::Serializer::serialize_none(serializer);
3097        }
3098        let mut map = serde::Serializer::serialize_map(serializer, None)?;
3099        if !self.extension.is_empty() {
3100            serde::ser::SerializeMap::serialize_entry(&mut map, "extension", &self.extension)?;
3101        }
3102        if let Some(id) = &self.id {
3103            serde::ser::SerializeMap::serialize_entry(&mut map, "id", id)?;
3104        }
3105        serde::ser::SerializeMap::end(map)
3106    }
3107
3108    fn from_json_parts(
3109        value: Option<&super::super::codec::Value>,
3110        element: Option<&super::super::codec::Value>,
3111        path: &mut super::super::codec::Path,
3112    ) -> Result<Self, super::super::codec::DecodeError> {
3113        if value.is_none() && element.is_none() && !path.is_lenient() {
3114            return Err(path.error(super::super::codec::DecodeErrorKind::MissingProperty));
3115        }
3116        let value = match value {
3117            Some(value) => {
3118                let value = super::super::codec::expect_single(value, path)?;
3119                Some(super::super::codec::expect_u32(value, 0, path)?)
3120            }
3121            None => None,
3122        };
3123        let mut id = None;
3124        let mut extension = Vec::new();
3125        if let Some(element) = element {
3126            let object = super::super::codec::expect_object(element, path)?;
3127            for (key, item) in object {
3128                match key.as_str() {
3129                    "id" => {
3130                        id = Some(path.with("id", |path| {
3131                            super::primitives::checked_string(
3132                                super::super::codec::expect_string(item, path)?,
3133                                path,
3134                            )
3135                        })?);
3136                    }
3137                    "extension" => {
3138                        for (index, entry) in super::super::codec::expect_array(item, path)?
3139                            .iter()
3140                            .enumerate()
3141                        {
3142                            extension.push(path.with_index("extension", index, |path| {
3143                                super::super::codec::Json::from_json(
3144                                    super::super::codec::expect_object(entry, path)?,
3145                                    path,
3146                                )
3147                            })?);
3148                        }
3149                    }
3150                    _ => {
3151                        return path.with(key, |path| {
3152                            Err(path.error(super::super::codec::DecodeErrorKind::UnknownProperty))
3153                        });
3154                    }
3155                }
3156            }
3157        }
3158        Ok(Self {
3159            id,
3160            extension,
3161            value,
3162        })
3163    }
3164}
3165
3166/// Primitive Type uri
3167///
3168/// String of characters used to identify a name or a resource
3169#[derive(Debug, Clone, Default, PartialEq, Eq)]
3170pub struct Uri {
3171    /// xml:id (or equivalent in JSON)
3172    ///
3173    /// unique id for the element within a resource (for internal references)
3174    pub id: Option<std::string::String>,
3175    /// Additional content defined by implementations
3176    ///
3177    /// May be used to represent additional information that is not part of the
3178    /// basic definition of the resource. To make the use of extensions safe and
3179    /// manageable, there is a strict set of governance applied to the definition
3180    /// and use of extensions. Though any implementer can define an extension, there
3181    /// is a set of requirements that SHALL be met as part of the definition of the
3182    /// extension.
3183    pub extension: Vec<super::extension::Extension>,
3184    /// Primitive value for uri
3185    ///
3186    /// The actual value
3187    pub value: Option<std::string::String>,
3188}
3189impl From<std::string::String> for Uri {
3190    fn from(value: std::string::String) -> Self {
3191        Self {
3192            value: Some(value),
3193            ..Self::default()
3194        }
3195    }
3196}
3197impl From<&str> for Uri {
3198    fn from(value: &str) -> Self {
3199        Self::from(std::string::String::from(value))
3200    }
3201}
3202
3203/// The lexical form of the FHIR primitive `uri`, anchored to the whole value.
3204///
3205/// The `regex` extension of `uri.value` states it (<https://hl7.org/fhir/R4/datatypes.html#primitive>),
3206/// and the form is an XML Schema pattern, where `\s` is the space, the tab,
3207/// the carriage return and the line feed alone (<https://www.w3.org/TR/xmlschema-2/#regexs>).
3208#[expect(
3209    clippy::expect_used,
3210    reason = "the emitter compiles every lexical form it writes, so the pattern holds"
3211)]
3212static URI_LEXICAL_FORM: std::sync::LazyLock<regex::bytes::Regex> =
3213    std::sync::LazyLock::new(|| {
3214        regex::bytes::RegexBuilder::new(r"^(?:\S*)$")
3215            .unicode(false)
3216            .build()
3217            .expect("the lexical form of `uri` should compile")
3218    });
3219
3220/// Hands back `text` when it keeps the lexical form of `uri`.
3221///
3222/// # Errors
3223///
3224/// Returns [`super::super::codec::DecodeErrorKind::BadValue`] at `path` for a value outside the form.
3225pub(crate) fn checked_uri(
3226    text: std::string::String,
3227    path: &super::super::codec::Path,
3228) -> Result<std::string::String, super::super::codec::DecodeError> {
3229    if URI_LEXICAL_FORM.is_match(text.as_bytes()) {
3230        Ok(text)
3231    } else {
3232        Err(path.error(super::super::codec::DecodeErrorKind::BadValue))
3233    }
3234}
3235
3236impl Uri {
3237    /// Checks `text` against the lexical form of `uri`, the one the decoder holds a value to.
3238    ///
3239    /// # Errors
3240    ///
3241    /// Returns [`super::super::codec::LexicalError`] naming `uri` when `text` is outside the form.
3242    pub fn check(text: &str) -> Result<(), super::super::codec::LexicalError> {
3243        if URI_LEXICAL_FORM.is_match(text.as_bytes()) {
3244            Ok(())
3245        } else {
3246            Err(super::super::codec::LexicalError { type_code: "uri" })
3247        }
3248    }
3249}
3250
3251impl super::super::codec::Primitive for Uri {
3252    fn value_json(
3253        &self,
3254    ) -> Result<Option<super::super::codec::Value>, super::super::codec::EncodeError> {
3255        Ok(self
3256            .value
3257            .as_ref()
3258            .map(|v| super::super::codec::Value::String(v.clone())))
3259    }
3260
3261    fn element_json(
3262        &self,
3263    ) -> Result<Option<super::super::codec::Value>, super::super::codec::EncodeError> {
3264        if self.id.is_none() && self.extension.is_empty() {
3265            return Ok(None);
3266        }
3267        let mut object = super::super::codec::Object::new();
3268        if let Some(id) = &self.id {
3269            object.insert(
3270                std::string::String::from("id"),
3271                super::super::codec::Value::String(id.clone()),
3272            );
3273        }
3274        if !self.extension.is_empty() {
3275            let mut items = Vec::with_capacity(self.extension.len());
3276            for item in &self.extension {
3277                items.push(super::super::codec::Value::Object(
3278                    super::super::codec::Json::to_json(item)?,
3279                ));
3280            }
3281            object.insert(
3282                std::string::String::from("extension"),
3283                super::super::codec::Value::Array(items),
3284            );
3285        }
3286        Ok(Some(super::super::codec::Value::Object(object)))
3287    }
3288
3289    fn has_value(&self) -> bool {
3290        self.value.is_some()
3291    }
3292
3293    fn has_element(&self) -> bool {
3294        self.id.is_some() || !self.extension.is_empty()
3295    }
3296
3297    fn serialize_value<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
3298        match self.value.as_ref() {
3299            Some(v) => serde::Serializer::serialize_str(serializer, v),
3300            None => serde::Serializer::serialize_none(serializer),
3301        }
3302    }
3303
3304    fn serialize_element<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
3305        if self.id.is_none() && self.extension.is_empty() {
3306            return serde::Serializer::serialize_none(serializer);
3307        }
3308        let mut map = serde::Serializer::serialize_map(serializer, None)?;
3309        if !self.extension.is_empty() {
3310            serde::ser::SerializeMap::serialize_entry(&mut map, "extension", &self.extension)?;
3311        }
3312        if let Some(id) = &self.id {
3313            serde::ser::SerializeMap::serialize_entry(&mut map, "id", id)?;
3314        }
3315        serde::ser::SerializeMap::end(map)
3316    }
3317
3318    fn from_json_parts(
3319        value: Option<&super::super::codec::Value>,
3320        element: Option<&super::super::codec::Value>,
3321        path: &mut super::super::codec::Path,
3322    ) -> Result<Self, super::super::codec::DecodeError> {
3323        if value.is_none() && element.is_none() && !path.is_lenient() {
3324            return Err(path.error(super::super::codec::DecodeErrorKind::MissingProperty));
3325        }
3326        let value = match value {
3327            Some(value) => {
3328                let value = super::super::codec::expect_single(value, path)?;
3329                Some(checked_uri(
3330                    super::super::codec::expect_string(value, path)?,
3331                    path,
3332                )?)
3333            }
3334            None => None,
3335        };
3336        let mut id = None;
3337        let mut extension = Vec::new();
3338        if let Some(element) = element {
3339            let object = super::super::codec::expect_object(element, path)?;
3340            for (key, item) in object {
3341                match key.as_str() {
3342                    "id" => {
3343                        id = Some(path.with("id", |path| {
3344                            super::primitives::checked_string(
3345                                super::super::codec::expect_string(item, path)?,
3346                                path,
3347                            )
3348                        })?);
3349                    }
3350                    "extension" => {
3351                        for (index, entry) in super::super::codec::expect_array(item, path)?
3352                            .iter()
3353                            .enumerate()
3354                        {
3355                            extension.push(path.with_index("extension", index, |path| {
3356                                super::super::codec::Json::from_json(
3357                                    super::super::codec::expect_object(entry, path)?,
3358                                    path,
3359                                )
3360                            })?);
3361                        }
3362                    }
3363                    _ => {
3364                        return path.with(key, |path| {
3365                            Err(path.error(super::super::codec::DecodeErrorKind::UnknownProperty))
3366                        });
3367                    }
3368                }
3369            }
3370        }
3371        Ok(Self {
3372            id,
3373            extension,
3374            value,
3375        })
3376    }
3377}
3378
3379/// Primitive Type url
3380///
3381/// A URI that is a literal reference
3382#[derive(Debug, Clone, Default, PartialEq, Eq)]
3383pub struct Url {
3384    /// xml:id (or equivalent in JSON)
3385    ///
3386    /// unique id for the element within a resource (for internal references)
3387    pub id: Option<std::string::String>,
3388    /// Additional content defined by implementations
3389    ///
3390    /// May be used to represent additional information that is not part of the
3391    /// basic definition of the resource. To make the use of extensions safe and
3392    /// manageable, there is a strict set of governance applied to the definition
3393    /// and use of extensions. Though any implementer can define an extension, there
3394    /// is a set of requirements that SHALL be met as part of the definition of the
3395    /// extension.
3396    pub extension: Vec<super::extension::Extension>,
3397    /// Primitive value for url
3398    pub value: Option<std::string::String>,
3399}
3400impl From<std::string::String> for Url {
3401    fn from(value: std::string::String) -> Self {
3402        Self {
3403            value: Some(value),
3404            ..Self::default()
3405        }
3406    }
3407}
3408impl From<&str> for Url {
3409    fn from(value: &str) -> Self {
3410        Self::from(std::string::String::from(value))
3411    }
3412}
3413
3414/// The lexical form of the FHIR primitive `url`, anchored to the whole value.
3415///
3416/// The `regex` extension of `url.value` states it (<https://hl7.org/fhir/R4/datatypes.html#primitive>),
3417/// and the form is an XML Schema pattern, where `\s` is the space, the tab,
3418/// the carriage return and the line feed alone (<https://www.w3.org/TR/xmlschema-2/#regexs>).
3419#[expect(
3420    clippy::expect_used,
3421    reason = "the emitter compiles every lexical form it writes, so the pattern holds"
3422)]
3423static URL_LEXICAL_FORM: std::sync::LazyLock<regex::bytes::Regex> =
3424    std::sync::LazyLock::new(|| {
3425        regex::bytes::RegexBuilder::new(r"^(?:\S*)$")
3426            .unicode(false)
3427            .build()
3428            .expect("the lexical form of `url` should compile")
3429    });
3430
3431/// Hands back `text` when it keeps the lexical form of `url`.
3432///
3433/// # Errors
3434///
3435/// Returns [`super::super::codec::DecodeErrorKind::BadValue`] at `path` for a value outside the form.
3436pub(crate) fn checked_url(
3437    text: std::string::String,
3438    path: &super::super::codec::Path,
3439) -> Result<std::string::String, super::super::codec::DecodeError> {
3440    if URL_LEXICAL_FORM.is_match(text.as_bytes()) {
3441        Ok(text)
3442    } else {
3443        Err(path.error(super::super::codec::DecodeErrorKind::BadValue))
3444    }
3445}
3446
3447impl Url {
3448    /// Checks `text` against the lexical form of `url`, the one the decoder holds a value to.
3449    ///
3450    /// # Errors
3451    ///
3452    /// Returns [`super::super::codec::LexicalError`] naming `url` when `text` is outside the form.
3453    pub fn check(text: &str) -> Result<(), super::super::codec::LexicalError> {
3454        if URL_LEXICAL_FORM.is_match(text.as_bytes()) {
3455            Ok(())
3456        } else {
3457            Err(super::super::codec::LexicalError { type_code: "url" })
3458        }
3459    }
3460}
3461
3462impl super::super::codec::Primitive for Url {
3463    fn value_json(
3464        &self,
3465    ) -> Result<Option<super::super::codec::Value>, super::super::codec::EncodeError> {
3466        Ok(self
3467            .value
3468            .as_ref()
3469            .map(|v| super::super::codec::Value::String(v.clone())))
3470    }
3471
3472    fn element_json(
3473        &self,
3474    ) -> Result<Option<super::super::codec::Value>, super::super::codec::EncodeError> {
3475        if self.id.is_none() && self.extension.is_empty() {
3476            return Ok(None);
3477        }
3478        let mut object = super::super::codec::Object::new();
3479        if let Some(id) = &self.id {
3480            object.insert(
3481                std::string::String::from("id"),
3482                super::super::codec::Value::String(id.clone()),
3483            );
3484        }
3485        if !self.extension.is_empty() {
3486            let mut items = Vec::with_capacity(self.extension.len());
3487            for item in &self.extension {
3488                items.push(super::super::codec::Value::Object(
3489                    super::super::codec::Json::to_json(item)?,
3490                ));
3491            }
3492            object.insert(
3493                std::string::String::from("extension"),
3494                super::super::codec::Value::Array(items),
3495            );
3496        }
3497        Ok(Some(super::super::codec::Value::Object(object)))
3498    }
3499
3500    fn has_value(&self) -> bool {
3501        self.value.is_some()
3502    }
3503
3504    fn has_element(&self) -> bool {
3505        self.id.is_some() || !self.extension.is_empty()
3506    }
3507
3508    fn serialize_value<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
3509        match self.value.as_ref() {
3510            Some(v) => serde::Serializer::serialize_str(serializer, v),
3511            None => serde::Serializer::serialize_none(serializer),
3512        }
3513    }
3514
3515    fn serialize_element<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
3516        if self.id.is_none() && self.extension.is_empty() {
3517            return serde::Serializer::serialize_none(serializer);
3518        }
3519        let mut map = serde::Serializer::serialize_map(serializer, None)?;
3520        if !self.extension.is_empty() {
3521            serde::ser::SerializeMap::serialize_entry(&mut map, "extension", &self.extension)?;
3522        }
3523        if let Some(id) = &self.id {
3524            serde::ser::SerializeMap::serialize_entry(&mut map, "id", id)?;
3525        }
3526        serde::ser::SerializeMap::end(map)
3527    }
3528
3529    fn from_json_parts(
3530        value: Option<&super::super::codec::Value>,
3531        element: Option<&super::super::codec::Value>,
3532        path: &mut super::super::codec::Path,
3533    ) -> Result<Self, super::super::codec::DecodeError> {
3534        if value.is_none() && element.is_none() && !path.is_lenient() {
3535            return Err(path.error(super::super::codec::DecodeErrorKind::MissingProperty));
3536        }
3537        let value = match value {
3538            Some(value) => {
3539                let value = super::super::codec::expect_single(value, path)?;
3540                Some(checked_url(
3541                    super::super::codec::expect_string(value, path)?,
3542                    path,
3543                )?)
3544            }
3545            None => None,
3546        };
3547        let mut id = None;
3548        let mut extension = Vec::new();
3549        if let Some(element) = element {
3550            let object = super::super::codec::expect_object(element, path)?;
3551            for (key, item) in object {
3552                match key.as_str() {
3553                    "id" => {
3554                        id = Some(path.with("id", |path| {
3555                            super::primitives::checked_string(
3556                                super::super::codec::expect_string(item, path)?,
3557                                path,
3558                            )
3559                        })?);
3560                    }
3561                    "extension" => {
3562                        for (index, entry) in super::super::codec::expect_array(item, path)?
3563                            .iter()
3564                            .enumerate()
3565                        {
3566                            extension.push(path.with_index("extension", index, |path| {
3567                                super::super::codec::Json::from_json(
3568                                    super::super::codec::expect_object(entry, path)?,
3569                                    path,
3570                                )
3571                            })?);
3572                        }
3573                    }
3574                    _ => {
3575                        return path.with(key, |path| {
3576                            Err(path.error(super::super::codec::DecodeErrorKind::UnknownProperty))
3577                        });
3578                    }
3579                }
3580            }
3581        }
3582        Ok(Self {
3583            id,
3584            extension,
3585            value,
3586        })
3587    }
3588}
3589
3590/// Primitive Type uuid
3591///
3592/// A UUID, represented as a URI
3593#[derive(Debug, Clone, Default, PartialEq, Eq)]
3594pub struct Uuid {
3595    /// xml:id (or equivalent in JSON)
3596    ///
3597    /// unique id for the element within a resource (for internal references)
3598    pub id: Option<std::string::String>,
3599    /// Additional content defined by implementations
3600    ///
3601    /// May be used to represent additional information that is not part of the
3602    /// basic definition of the resource. To make the use of extensions safe and
3603    /// manageable, there is a strict set of governance applied to the definition
3604    /// and use of extensions. Though any implementer can define an extension, there
3605    /// is a set of requirements that SHALL be met as part of the definition of the
3606    /// extension.
3607    pub extension: Vec<super::extension::Extension>,
3608    /// Primitive value for uuid
3609    pub value: Option<std::string::String>,
3610}
3611impl From<std::string::String> for Uuid {
3612    fn from(value: std::string::String) -> Self {
3613        Self {
3614            value: Some(value),
3615            ..Self::default()
3616        }
3617    }
3618}
3619impl From<&str> for Uuid {
3620    fn from(value: &str) -> Self {
3621        Self::from(std::string::String::from(value))
3622    }
3623}
3624
3625/// The lexical form of the FHIR primitive `uuid`, anchored to the whole value.
3626///
3627/// The `regex` extension of `uuid.value` states it (<https://hl7.org/fhir/R4/datatypes.html#primitive>),
3628/// and the form is an XML Schema pattern, where `\s` is the space, the tab,
3629/// the carriage return and the line feed alone (<https://www.w3.org/TR/xmlschema-2/#regexs>).
3630#[expect(
3631    clippy::expect_used,
3632    reason = "the emitter compiles every lexical form it writes, so the pattern holds"
3633)]
3634static UUID_LEXICAL_FORM: std::sync::LazyLock<regex::bytes::Regex> =
3635    std::sync::LazyLock::new(|| {
3636        regex::bytes::RegexBuilder::new(
3637            r"^(?:urn:uuid:[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})$",
3638        )
3639        .unicode(false)
3640        .build()
3641        .expect("the lexical form of `uuid` should compile")
3642    });
3643
3644/// Hands back `text` when it keeps the lexical form of `uuid`.
3645///
3646/// # Errors
3647///
3648/// Returns [`super::super::codec::DecodeErrorKind::BadValue`] at `path` for a value outside the form.
3649pub(crate) fn checked_uuid(
3650    text: std::string::String,
3651    path: &super::super::codec::Path,
3652) -> Result<std::string::String, super::super::codec::DecodeError> {
3653    if UUID_LEXICAL_FORM.is_match(text.as_bytes()) {
3654        Ok(text)
3655    } else {
3656        Err(path.error(super::super::codec::DecodeErrorKind::BadValue))
3657    }
3658}
3659
3660impl Uuid {
3661    /// Checks `text` against the lexical form of `uuid`, the one the decoder holds a value to.
3662    ///
3663    /// # Errors
3664    ///
3665    /// Returns [`super::super::codec::LexicalError`] naming `uuid` when `text` is outside the form.
3666    pub fn check(text: &str) -> Result<(), super::super::codec::LexicalError> {
3667        if UUID_LEXICAL_FORM.is_match(text.as_bytes()) {
3668            Ok(())
3669        } else {
3670            Err(super::super::codec::LexicalError { type_code: "uuid" })
3671        }
3672    }
3673}
3674
3675impl super::super::codec::Primitive for Uuid {
3676    fn value_json(
3677        &self,
3678    ) -> Result<Option<super::super::codec::Value>, super::super::codec::EncodeError> {
3679        Ok(self
3680            .value
3681            .as_ref()
3682            .map(|v| super::super::codec::Value::String(v.clone())))
3683    }
3684
3685    fn element_json(
3686        &self,
3687    ) -> Result<Option<super::super::codec::Value>, super::super::codec::EncodeError> {
3688        if self.id.is_none() && self.extension.is_empty() {
3689            return Ok(None);
3690        }
3691        let mut object = super::super::codec::Object::new();
3692        if let Some(id) = &self.id {
3693            object.insert(
3694                std::string::String::from("id"),
3695                super::super::codec::Value::String(id.clone()),
3696            );
3697        }
3698        if !self.extension.is_empty() {
3699            let mut items = Vec::with_capacity(self.extension.len());
3700            for item in &self.extension {
3701                items.push(super::super::codec::Value::Object(
3702                    super::super::codec::Json::to_json(item)?,
3703                ));
3704            }
3705            object.insert(
3706                std::string::String::from("extension"),
3707                super::super::codec::Value::Array(items),
3708            );
3709        }
3710        Ok(Some(super::super::codec::Value::Object(object)))
3711    }
3712
3713    fn has_value(&self) -> bool {
3714        self.value.is_some()
3715    }
3716
3717    fn has_element(&self) -> bool {
3718        self.id.is_some() || !self.extension.is_empty()
3719    }
3720
3721    fn serialize_value<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
3722        match self.value.as_ref() {
3723            Some(v) => serde::Serializer::serialize_str(serializer, v),
3724            None => serde::Serializer::serialize_none(serializer),
3725        }
3726    }
3727
3728    fn serialize_element<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
3729        if self.id.is_none() && self.extension.is_empty() {
3730            return serde::Serializer::serialize_none(serializer);
3731        }
3732        let mut map = serde::Serializer::serialize_map(serializer, None)?;
3733        if !self.extension.is_empty() {
3734            serde::ser::SerializeMap::serialize_entry(&mut map, "extension", &self.extension)?;
3735        }
3736        if let Some(id) = &self.id {
3737            serde::ser::SerializeMap::serialize_entry(&mut map, "id", id)?;
3738        }
3739        serde::ser::SerializeMap::end(map)
3740    }
3741
3742    fn from_json_parts(
3743        value: Option<&super::super::codec::Value>,
3744        element: Option<&super::super::codec::Value>,
3745        path: &mut super::super::codec::Path,
3746    ) -> Result<Self, super::super::codec::DecodeError> {
3747        if value.is_none() && element.is_none() && !path.is_lenient() {
3748            return Err(path.error(super::super::codec::DecodeErrorKind::MissingProperty));
3749        }
3750        let value = match value {
3751            Some(value) => {
3752                let value = super::super::codec::expect_single(value, path)?;
3753                Some(checked_uuid(
3754                    super::super::codec::expect_string(value, path)?,
3755                    path,
3756                )?)
3757            }
3758            None => None,
3759        };
3760        let mut id = None;
3761        let mut extension = Vec::new();
3762        if let Some(element) = element {
3763            let object = super::super::codec::expect_object(element, path)?;
3764            for (key, item) in object {
3765                match key.as_str() {
3766                    "id" => {
3767                        id = Some(path.with("id", |path| {
3768                            super::primitives::checked_string(
3769                                super::super::codec::expect_string(item, path)?,
3770                                path,
3771                            )
3772                        })?);
3773                    }
3774                    "extension" => {
3775                        for (index, entry) in super::super::codec::expect_array(item, path)?
3776                            .iter()
3777                            .enumerate()
3778                        {
3779                            extension.push(path.with_index("extension", index, |path| {
3780                                super::super::codec::Json::from_json(
3781                                    super::super::codec::expect_object(entry, path)?,
3782                                    path,
3783                                )
3784                            })?);
3785                        }
3786                    }
3787                    _ => {
3788                        return path.with(key, |path| {
3789                            Err(path.error(super::super::codec::DecodeErrorKind::UnknownProperty))
3790                        });
3791                    }
3792                }
3793            }
3794        }
3795        Ok(Self {
3796            id,
3797            extension,
3798            value,
3799        })
3800    }
3801}
3802
3803/// Primitive Type xhtml
3804///
3805/// XHTML
3806#[derive(Debug, Clone, Default, PartialEq, Eq)]
3807pub struct Xhtml {
3808    /// xml:id (or equivalent in JSON)
3809    ///
3810    /// unique id for the element within a resource (for internal references)
3811    pub id: Option<std::string::String>,
3812    /// Actual xhtml
3813    pub value: std::string::String,
3814}
3815impl From<std::string::String> for Xhtml {
3816    fn from(value: std::string::String) -> Self {
3817        Self {
3818            value,
3819            ..Self::default()
3820        }
3821    }
3822}
3823impl From<&str> for Xhtml {
3824    fn from(value: &str) -> Self {
3825        Self::from(std::string::String::from(value))
3826    }
3827}
3828
3829impl super::super::codec::Primitive for Xhtml {
3830    fn value_json(
3831        &self,
3832    ) -> Result<Option<super::super::codec::Value>, super::super::codec::EncodeError> {
3833        Ok(Some(&self.value).map(|v| super::super::codec::Value::String(v.clone())))
3834    }
3835
3836    fn element_json(
3837        &self,
3838    ) -> Result<Option<super::super::codec::Value>, super::super::codec::EncodeError> {
3839        if self.id.is_none() {
3840            return Ok(None);
3841        }
3842        let mut object = super::super::codec::Object::new();
3843        if let Some(id) = &self.id {
3844            object.insert(
3845                std::string::String::from("id"),
3846                super::super::codec::Value::String(id.clone()),
3847            );
3848        }
3849        Ok(Some(super::super::codec::Value::Object(object)))
3850    }
3851
3852    fn has_value(&self) -> bool {
3853        true
3854    }
3855
3856    fn has_element(&self) -> bool {
3857        self.id.is_some()
3858    }
3859
3860    fn serialize_value<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
3861        serde::Serializer::serialize_str(serializer, &self.value)
3862    }
3863
3864    fn serialize_element<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
3865        if self.id.is_none() {
3866            return serde::Serializer::serialize_none(serializer);
3867        }
3868        let mut map = serde::Serializer::serialize_map(serializer, None)?;
3869        if let Some(id) = &self.id {
3870            serde::ser::SerializeMap::serialize_entry(&mut map, "id", id)?;
3871        }
3872        serde::ser::SerializeMap::end(map)
3873    }
3874
3875    fn from_json_parts(
3876        value: Option<&super::super::codec::Value>,
3877        element: Option<&super::super::codec::Value>,
3878        path: &mut super::super::codec::Path,
3879    ) -> Result<Self, super::super::codec::DecodeError> {
3880        if value.is_none() && element.is_none() && !path.is_lenient() {
3881            return Err(path.error(super::super::codec::DecodeErrorKind::MissingProperty));
3882        }
3883        let value = match value {
3884            Some(value) => {
3885                let value = super::super::codec::expect_single(value, path)?;
3886                Some(super::super::codec::expect_string(value, path)?)
3887            }
3888            None => None,
3889        };
3890        let value = value
3891            .ok_or_else(|| path.error(super::super::codec::DecodeErrorKind::MissingProperty))?;
3892        let mut id = None;
3893        if let Some(element) = element {
3894            let object = super::super::codec::expect_object(element, path)?;
3895            for (key, item) in object {
3896                match key.as_str() {
3897                    "id" => {
3898                        id =
3899                            Some(path.with("id", |path| {
3900                                super::super::codec::expect_string(item, path)
3901                            })?);
3902                    }
3903                    _ => {
3904                        return path.with(key, |path| {
3905                            Err(path.error(super::super::codec::DecodeErrorKind::UnknownProperty))
3906                        });
3907                    }
3908                }
3909            }
3910        }
3911        Ok(Self { id, value })
3912    }
3913}
3914
3915/// Checks `value` as the JSON value of the FHIR primitive `code`: its JSON type,
3916/// its lexical form and, for an integer type, its range, exactly as the decoder does
3917/// (<https://hl7.org/fhir/R4/datatypes.html#primitive>).
3918///
3919/// Answers `None` when this version defines no primitive named `code`.
3920///
3921/// # Errors
3922///
3923/// The inner result is the decoder's [`super::super::codec::DecodeError`] at the path `code` for a value
3924/// the primitive refuses.
3925#[must_use]
3926pub fn check_value(
3927    code: &str,
3928    value: &super::super::codec::Value,
3929) -> Option<Result<(), super::super::codec::DecodeError>> {
3930    let mut path = super::super::codec::Path::root(code);
3931    let checked = match code {
3932        #[cfg(feature = "terminology")]
3933        "base64Binary" => <Base64Binary as super::super::codec::Primitive>::from_json_parts(
3934            Some(value),
3935            None,
3936            &mut path,
3937        )
3938        .map(|_| ()),
3939        #[cfg(feature = "terminology")]
3940        "boolean" => <Boolean as super::super::codec::Primitive>::from_json_parts(
3941            Some(value),
3942            None,
3943            &mut path,
3944        )
3945        .map(|_| ()),
3946        #[cfg(feature = "terminology")]
3947        "canonical" => <Canonical as super::super::codec::Primitive>::from_json_parts(
3948            Some(value),
3949            None,
3950            &mut path,
3951        )
3952        .map(|_| ()),
3953        #[cfg(feature = "terminology")]
3954        "code" => {
3955            <Code as super::super::codec::Primitive>::from_json_parts(Some(value), None, &mut path)
3956                .map(|_| ())
3957        }
3958        #[cfg(feature = "terminology")]
3959        "date" => {
3960            <Date as super::super::codec::Primitive>::from_json_parts(Some(value), None, &mut path)
3961                .map(|_| ())
3962        }
3963        #[cfg(feature = "terminology")]
3964        "dateTime" => <DateTime as super::super::codec::Primitive>::from_json_parts(
3965            Some(value),
3966            None,
3967            &mut path,
3968        )
3969        .map(|_| ()),
3970        #[cfg(feature = "terminology")]
3971        "decimal" => <Decimal as super::super::codec::Primitive>::from_json_parts(
3972            Some(value),
3973            None,
3974            &mut path,
3975        )
3976        .map(|_| ()),
3977        #[cfg(feature = "terminology")]
3978        "id" => {
3979            <Id as super::super::codec::Primitive>::from_json_parts(Some(value), None, &mut path)
3980                .map(|_| ())
3981        }
3982        #[cfg(feature = "terminology")]
3983        "instant" => <Instant as super::super::codec::Primitive>::from_json_parts(
3984            Some(value),
3985            None,
3986            &mut path,
3987        )
3988        .map(|_| ()),
3989        #[cfg(feature = "terminology")]
3990        "integer" => <Integer as super::super::codec::Primitive>::from_json_parts(
3991            Some(value),
3992            None,
3993            &mut path,
3994        )
3995        .map(|_| ()),
3996        #[cfg(feature = "terminology")]
3997        "markdown" => <Markdown as super::super::codec::Primitive>::from_json_parts(
3998            Some(value),
3999            None,
4000            &mut path,
4001        )
4002        .map(|_| ()),
4003        #[cfg(feature = "terminology")]
4004        "oid" => {
4005            <Oid as super::super::codec::Primitive>::from_json_parts(Some(value), None, &mut path)
4006                .map(|_| ())
4007        }
4008        #[cfg(feature = "terminology")]
4009        "positiveInt" => <PositiveInt as super::super::codec::Primitive>::from_json_parts(
4010            Some(value),
4011            None,
4012            &mut path,
4013        )
4014        .map(|_| ()),
4015        #[cfg(feature = "terminology")]
4016        "string" => <String as super::super::codec::Primitive>::from_json_parts(
4017            Some(value),
4018            None,
4019            &mut path,
4020        )
4021        .map(|_| ()),
4022        #[cfg(feature = "terminology")]
4023        "time" => {
4024            <Time as super::super::codec::Primitive>::from_json_parts(Some(value), None, &mut path)
4025                .map(|_| ())
4026        }
4027        #[cfg(feature = "terminology")]
4028        "unsignedInt" => <UnsignedInt as super::super::codec::Primitive>::from_json_parts(
4029            Some(value),
4030            None,
4031            &mut path,
4032        )
4033        .map(|_| ()),
4034        #[cfg(feature = "terminology")]
4035        "uri" => {
4036            <Uri as super::super::codec::Primitive>::from_json_parts(Some(value), None, &mut path)
4037                .map(|_| ())
4038        }
4039        #[cfg(feature = "terminology")]
4040        "url" => {
4041            <Url as super::super::codec::Primitive>::from_json_parts(Some(value), None, &mut path)
4042                .map(|_| ())
4043        }
4044        #[cfg(feature = "terminology")]
4045        "uuid" => {
4046            <Uuid as super::super::codec::Primitive>::from_json_parts(Some(value), None, &mut path)
4047                .map(|_| ())
4048        }
4049        #[cfg(feature = "terminology")]
4050        "xhtml" => {
4051            <Xhtml as super::super::codec::Primitive>::from_json_parts(Some(value), None, &mut path)
4052                .map(|_| ())
4053        }
4054        _ => return None,
4055    };
4056    Some(checked)
4057}