haste_fhir_model/r4/
sqlx.rs1use crate::r4::generated::resources::ResourceType;
2use sqlx::{
3 Database, Decode, Encode, Postgres,
4 encode::IsNull,
5 error::BoxDynError,
6 postgres::{PgArgumentBuffer, PgTypeInfo, PgValueRef},
7};
8use std::io::Write;
9
10#[derive(Debug, Clone)]
11pub struct FHIRJson<T: ?Sized>(pub T);
12
13impl<T> sqlx::Type<Postgres> for FHIRJson<T>
14where
15 T: serde::Serialize + serde::de::DeserializeOwned,
16{
17 fn type_info() -> PgTypeInfo {
18 PgTypeInfo::with_name("jsonb")
19 }
20
21 fn compatible(ty: &PgTypeInfo) -> bool {
22 *ty == PgTypeInfo::with_name("json") || *ty == PgTypeInfo::with_name("jsonb")
23 }
24}
25
26impl<'r, T: 'r> Decode<'r, Postgres> for FHIRJson<T>
27where
28 T: serde::Serialize + serde::Deserialize<'r>,
29{
30 fn decode(value: PgValueRef<'r>) -> Result<Self, BoxDynError> {
31 let buf = value.as_bytes()?;
32 let resource = serde_json::from_slice::<T>(&buf[1..]);
34 Ok(FHIRJson::<T>(resource?))
35 }
36}
37
38pub struct FHIRJsonRef<'a, T: ?Sized>(pub &'a T);
40impl<'a, T> sqlx::Type<Postgres> for FHIRJsonRef<'a, T>
41where
42 T: serde::Serialize + serde::de::DeserializeOwned,
43{
44 fn type_info() -> PgTypeInfo {
45 PgTypeInfo::with_name("jsonb")
46 }
47
48 fn compatible(ty: &PgTypeInfo) -> bool {
49 *ty == PgTypeInfo::with_name("json") || *ty == PgTypeInfo::with_name("jsonb")
50 }
51}
52
53impl<'q, T> Encode<'q, Postgres> for FHIRJsonRef<'q, T>
54where
55 T: serde::Serialize + serde::de::DeserializeOwned,
56{
57 fn encode_by_ref(&self, buf: &mut PgArgumentBuffer) -> Result<IsNull, BoxDynError> {
58 buf.push(1);
69
70 serde_json::to_writer(&mut **buf, &*self.0)?;
72
73 Ok(IsNull::No)
74 }
75}
76
77impl<'r, DB: Database> Decode<'r, DB> for ResourceType
78where
79 &'r str: Decode<'r, DB>,
80{
81 fn decode(
82 value: <DB as Database>::ValueRef<'r>,
83 ) -> Result<ResourceType, Box<dyn std::error::Error + 'static + Send + Sync>> {
84 let value = <&str as Decode<DB>>::decode(value)?;
85 Ok(ResourceType::try_from(value).unwrap())
86 }
87}
88
89impl<'r> Encode<'r, Postgres> for ResourceType {
90 fn encode_by_ref(
91 &self,
92 buf: &mut PgArgumentBuffer,
93 ) -> Result<sqlx::encode::IsNull, sqlx::error::BoxDynError> {
94 buf.write(self.as_ref().as_bytes())?;
95 Ok(sqlx::encode::IsNull::No)
96 }
97}