Skip to main content

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