fhir_sdk/client/fhir/
write.rs1use std::future::Future;
4
5use fhir_model::for_all_versions;
6use reqwest::StatusCode;
7use serde::Serialize;
8
9use super::{Client, Error};
10use crate::{
11 extensions::{AnyResource, GenericResource},
12 version::{FhirVersion, fhir_version},
13};
14
15pub trait ResourceWrite<Version>: Serialize + Send + Sync {
18 fn update(
21 &mut self,
22 conditional: bool,
23 client: &Client<Version>,
24 ) -> impl Future<Output = Result<bool, Error>> + Send;
25 fn create(
27 &mut self,
28 client: &Client<Version>,
29 ) -> impl Future<Output = Result<String, Error>> + Send;
30 fn delete(self, client: &Client<Version>) -> impl Future<Output = Result<(), Error>> + Send;
32}
33
34impl<R, V> ResourceWrite<V> for R
35where
36 R: AnyResource<V> + Serialize + Send + Sync,
37 V: FhirVersion,
38 (StatusCode, V::OperationOutcome): Into<Error>,
39{
40 async fn update(&mut self, conditional: bool, client: &Client<V>) -> Result<bool, Error> {
41 let id = self.id().ok_or(Error::MissingId)?;
42 let version_id =
43 conditional.then(|| self.version_id().ok_or(Error::MissingVersionId)).transpose()?;
44 let (created, version_id) =
45 client.update_generic(R::TYPE_STR, id, self, version_id).await?;
46 self.set_version_id(version_id);
47 Ok(created)
48 }
49
50 async fn create(&mut self, client: &Client<V>) -> Result<String, Error> {
51 let (id, version_id) = client.create_generic(R::TYPE_STR, self).await?;
52 self.set_id(id.clone());
53 if let Some(version) = version_id {
54 self.set_version_id(version);
55 }
56 Ok(id)
57 }
58
59 async fn delete(self, client: &Client<V>) -> Result<(), Error> {
60 let id = self.id().ok_or(Error::MissingId)?;
61 client.delete(R::TYPE, id).await?;
62 Ok(())
63 }
64}
65
66pub trait AnyResourceWrite: Serialize + Send + Sync {
73 type Version: FhirVersion;
75
76 fn update(
79 &mut self,
80 conditional: bool,
81 client: &Client<Self::Version>,
82 ) -> impl Future<Output = Result<bool, Error>> + Send;
83 fn create(
85 &mut self,
86 client: &Client<Self::Version>,
87 ) -> impl Future<Output = Result<String, Error>> + Send;
88 fn delete(
90 self,
91 client: &Client<Self::Version>,
92 ) -> impl Future<Output = Result<(), Error>> + Send;
93}
94
95macro_rules! impl_generic_resource_write {
99 ($version:ident) => {
100 use fhir_model::$version;
101
102 impl AnyResourceWrite for $version::resources::Resource {
103 type Version = fhir_version!($version);
104
105 async fn update(
106 &mut self,
107 conditional: bool,
108 client: &Client<Self::Version>,
109 ) -> Result<bool, Error> {
110 let id = self.as_base_resource().id().as_deref().ok_or(Error::MissingId)?;
111 let version_id = conditional
112 .then(|| self.version_id().ok_or(Error::MissingVersionId))
113 .transpose()?;
114 let (created, version_id) = client
115 .update_generic(self.resource_type().as_str(), id, self, version_id)
116 .await?;
117 self.set_version_id(version_id);
118 Ok(created)
119 }
120
121 async fn create(&mut self, client: &Client<Self::Version>) -> Result<String, Error> {
122 let (id, version_id) =
123 client.create_generic(self.resource_type().as_str(), self).await?;
124 self.as_base_resource_mut().set_id(Some(id.clone()));
125 if let Some(version) = version_id {
126 self.set_version_id(version);
127 }
128 Ok(id)
129 }
130
131 async fn delete(self, client: &Client<Self::Version>) -> Result<(), Error> {
132 let id = self.as_base_resource().id().as_deref().ok_or(Error::MissingId)?;
133 client.delete(self.resource_type(), id).await?;
134 Ok(())
135 }
136 }
137 };
138}
139for_all_versions!(impl_generic_resource_write);