Skip to main content

fhir_types/r6/
primitives.rs

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