fhir_model/
lib.rs

1//! # FHIR Models.
2//!
3//! This is a sub-crate of [`fhir-sdk`](https://crates.io/crates/fhir-sdk). Please take a look at the main crate for
4//! more documentation.
5
6mod bundle;
7mod concepts;
8mod date_time;
9mod error;
10mod identifiable_resource;
11#[cfg(feature = "r4b")]
12pub mod r4b;
13#[cfg(feature = "r5")]
14pub mod r5;
15mod references;
16mod resource_type;
17#[cfg(feature = "stu3")]
18pub mod stu3;
19
20use std::ops::{Deref, DerefMut};
21
22use base64::prelude::{BASE64_STANDARD, Engine};
23use serde::{Deserialize, Serialize};
24pub use time;
25
26pub use self::{date_time::*, error::*, references::*};
27
28/// Run a macro for all activated FHIR versions to implement similar things for
29/// different FHIR versions.
30#[macro_export]
31macro_rules! for_all_versions {
32	($macro:ident) => {
33		for_all_versions!(@inner $macro [stu3 = "stu3", r4b = "r4b", r5 = "r5"]);
34	};
35	(@inner $macro:ident [$($version:ident = $feature:literal),*]) => {
36		$(
37			#[cfg(feature = $feature)]
38			$macro!($version);
39		)*
40	};
41}
42
43/// FHIR `integer64` type. Wraps an i64, but serializes and deserializes as
44/// string.
45#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
46pub struct Integer64(pub i64);
47
48impl Serialize for Integer64 {
49	fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
50	where
51		S: serde::Serializer,
52	{
53		self.0.to_string().serialize(serializer)
54	}
55}
56
57impl<'de> Deserialize<'de> for Integer64 {
58	fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
59	where
60		D: serde::Deserializer<'de>,
61	{
62		let s = String::deserialize(deserializer)?;
63		let i = s.parse().map_err(serde::de::Error::custom)?;
64		Ok(Self(i))
65	}
66}
67
68/// FHIR `base64Binary` type. Wraps binary data and serializes to base64
69/// strings.
70#[derive(Debug, Clone, PartialEq, Eq, Hash, Default)]
71pub struct Base64Binary(pub Vec<u8>);
72
73impl Serialize for Base64Binary {
74	fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
75	where
76		S: serde::Serializer,
77	{
78		let s = BASE64_STANDARD.encode(&self.0);
79		s.serialize(serializer)
80	}
81}
82
83impl<'de> Deserialize<'de> for Base64Binary {
84	fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
85	where
86		D: serde::Deserializer<'de>,
87	{
88		let mut s = String::deserialize(deserializer)?;
89		s.retain(|c| !c.is_whitespace());
90		let bytes = BASE64_STANDARD.decode(s).map_err(serde::de::Error::custom)?;
91		Ok(Self(bytes))
92	}
93}
94
95/// Deref and From implementations for wrappers.
96macro_rules! wrapper_impls {
97	($wrapper:ident, $inner_type:ty) => {
98		impl Deref for $wrapper {
99			type Target = $inner_type;
100
101			fn deref(&self) -> &Self::Target {
102				&self.0
103			}
104		}
105
106		impl DerefMut for $wrapper {
107			fn deref_mut(&mut self) -> &mut Self::Target {
108				&mut self.0
109			}
110		}
111
112		impl From<$inner_type> for $wrapper {
113			fn from(inner: $inner_type) -> Self {
114				Self(inner)
115			}
116		}
117
118		impl From<$wrapper> for $inner_type {
119			fn from(wrapper: $wrapper) -> $inner_type {
120				wrapper.0
121			}
122		}
123	};
124}
125
126wrapper_impls!(Integer64, i64);
127wrapper_impls!(Base64Binary, Vec<u8>);
128wrapper_impls!(Time, time::Time);
129wrapper_impls!(Instant, time::OffsetDateTime);