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)]
11pub struct FHIRJson<T: ?Sized>(pub T);
12
13impl<T> sqlx::Type<Postgres> for FHIRJson<T>
14where
15 T: haste_fhir_serialization_json::FHIRJSONSerializer
16 + haste_fhir_serialization_json::FHIRJSONDeserializer,
17{
18 fn type_info() -> PgTypeInfo {
19 PgTypeInfo::with_name("jsonb")
20 }
21
22 fn compatible(ty: &PgTypeInfo) -> bool {
23 *ty == PgTypeInfo::with_name("json") || *ty == PgTypeInfo::with_name("jsonb")
24 }
25}
26
27impl<'r, T: 'r> Decode<'r, Postgres> for FHIRJson<T>
28where
29 T: haste_fhir_serialization_json::FHIRJSONSerializer
30 + haste_fhir_serialization_json::FHIRJSONDeserializer,
31{
32 fn decode(value: PgValueRef<'r>) -> Result<Self, BoxDynError> {
33 let buf = value.as_bytes()?;
34 let resource = haste_fhir_serialization_json::from_bytes::<T>(&buf[1..]);
36 Ok(FHIRJson::<T>(resource?))
37 }
38}
39
40pub struct FHIRJsonRef<'a, T: ?Sized>(pub &'a T);
42impl<'a, T> sqlx::Type<Postgres> for FHIRJsonRef<'a, T>
43where
44 T: haste_fhir_serialization_json::FHIRJSONSerializer
45 + haste_fhir_serialization_json::FHIRJSONDeserializer,
46{
47 fn type_info() -> PgTypeInfo {
48 PgTypeInfo::with_name("jsonb")
49 }
50
51 fn compatible(ty: &PgTypeInfo) -> bool {
52 *ty == PgTypeInfo::with_name("json") || *ty == PgTypeInfo::with_name("jsonb")
53 }
54}
55
56impl<'q, T> Encode<'q, Postgres> for FHIRJsonRef<'q, T>
57where
58 T: haste_fhir_serialization_json::FHIRJSONSerializer
59 + haste_fhir_serialization_json::FHIRJSONDeserializer,
60{
61 fn encode_by_ref(&self, buf: &mut PgArgumentBuffer) -> Result<IsNull, BoxDynError> {
62 buf.push(1);
73
74 haste_fhir_serialization_json::to_writer(&mut **buf, &*self.0)?;
76
77 Ok(IsNull::No)
78 }
79}
80
81impl<'r, DB: Database> Decode<'r, DB> for ResourceType
82where
83 &'r str: Decode<'r, DB>,
84{
85 fn decode(
86 value: <DB as Database>::ValueRef<'r>,
87 ) -> Result<ResourceType, Box<dyn std::error::Error + 'static + Send + Sync>> {
88 let value = <&str as Decode<DB>>::decode(value)?;
89 Ok(ResourceType::try_from(value).unwrap())
90 }
91}
92
93impl<'r> Encode<'r, Postgres> for ResourceType {
94 fn encode_by_ref(
95 &self,
96 buf: &mut PgArgumentBuffer,
97 ) -> Result<sqlx::encode::IsNull, sqlx::error::BoxDynError> {
98 buf.write(self.as_ref().as_bytes())?;
99 Ok(sqlx::encode::IsNull::No)
100 }
101}