oxinat_core/protocols/
delete.rs1use async_trait::async_trait;
2
3use crate::uri::data::resources::ResourcesUriBuilder;
4use crate::UriBuilder;
5use crate::client::{Xnat, ClientCore, ClientREST};
6use crate::models::{Experiment, Project, Resource, Scan, Subject};
7use crate::uri::data::{ExperimentUri, ProjectUriLegacy, SubjectUriLegacy};
8use crate::version::Version;
9use super::crud::{CrudError, Delete};
10
11macro_rules! acquire_identifier {
16 ($attr:expr, $error:literal) => {
17 $attr.take().ok_or(CrudError::IdentifierRequired($error.to_string()))
18 };
19}
20
21#[async_trait(?Send)]
22impl<V> Delete<Project> for Xnat<V>
23where
24 Self: ClientCore<Version = V> + ClientREST,
25 V: Version + ProjectUriLegacy,
26{
27 async fn delete_once(&self, model: Project) -> anyhow::Result<Project> {
28 let mut model_clone = model.clone();
29 let project = acquire_identifier!(model_clone.id, "project id")?;
30
31 self.delete(&self.version().project_data().with_id(project))
32 .await?
33 .send()
34 .await?;
35 Ok(model)
36 }
37}
38
39#[async_trait(?Send)]
40impl<V> Delete<Subject> for Xnat<V>
41where
42 Self: ClientCore<Version = V> + ClientREST,
43 V: Version + ProjectUriLegacy + SubjectUriLegacy,
44{
45 async fn delete_once(&self, model: Subject) -> anyhow::Result<Subject> {
46 let mut model_clone = model.clone();
47 let project = acquire_identifier!(model_clone.project, "project id")?;
48 let subject = acquire_identifier!(
49 model_clone
50 .label
51 .as_ref()
52 .or(model_clone.id.as_ref()),
53 "subject id")?;
54
55 let uri = self.version()
56 .project_data()
57 .with_id(project)
58 .subjects()
59 .with_subject(subject);
60 self.delete(&uri).await?.send().await?;
61 Ok(model)
62 }
63}
64
65#[async_trait(?Send)]
66impl<V> Delete<Experiment> for Xnat<V>
67where
68 Self: ClientCore<Version = V> + ClientREST,
69 V: Version + ExperimentUri + ProjectUriLegacy + SubjectUriLegacy,
70{
71 async fn delete_once(&self, model: Experiment) -> anyhow::Result<Experiment> {
72 let model_clone = model.clone();
73 let project = acquire_identifier!(
74 model_clone
75 .project
76 .as_ref()
77 .or(model_clone.subject_project.as_ref()),
78 "project id")?;
79 let subject = acquire_identifier!(
80 model_clone
81 .subject_label
82 .as_ref()
83 .or(model_clone.subject_id.as_ref()),
84 "subject id")?;
85 let session = acquire_identifier!(
86 model_clone
87 .id
88 .as_ref()
89 .or(model_clone.label.as_ref()),
90 "experiment id")?;
91
92 let uri = self.version()
93 .project_data()
94 .with_id(project)
95 .subjects()
96 .with_subject(subject)
97 .experiments()
98 .with_experiment(session);
99 self.delete(&uri).await?.send().await?;
100 Ok(model)
101 }
102}
103
104#[async_trait(?Send)]
105impl<V> Delete<Scan> for Xnat<V>
106where
107 Self: ClientCore<Version = V> + ClientREST,
108 V: Version + ExperimentUri + ProjectUriLegacy + SubjectUriLegacy,
109{
110 async fn delete_once(&self, model: Scan) -> anyhow::Result<Scan> {
111 let mut model_clone = model.clone();
112
113 let project = acquire_identifier!(
114 model_clone.project,
115 "project id")?;
116 let subject = acquire_identifier!(
117 model_clone.subject,
118 "subject id")?;
119 let session = acquire_identifier!(
120 model_clone.experiment,
121 "experiment id")?;
122 let scan = acquire_identifier!(model_clone.id, "scan id")?;
123
124 let uri = self.version()
125 .project_data()
126 .with_id(project)
127 .subjects()
128 .with_subject(subject)
129 .experiments()
130 .with_experiment(session);
131 self.delete(&uri.scans().with_scan(scan)).await?.send().await?;
132 Ok(model)
133 }
134}
135
136#[async_trait(?Send)]
137impl<V> Delete<Resource> for Xnat<V>
138where
139 Self: ClientCore<Version = V> + ClientREST,
140 V: Version + ExperimentUri + ProjectUriLegacy + SubjectUriLegacy,
141{
142 async fn delete_once(&self, model: Resource) -> anyhow::Result<Resource> {
143 let uri = match &model {
144 Resource {
145 project: Some(pjt),
146 subject: Some(sbj),
147 experiment: Some(exp),
148 scan: Some(scn),
149 ..
150 } => {
151 self
152 .version()
153 .project_data()
154 .with_id(pjt)
155 .subjects()
156 .with_subject(sbj)
157 .experiments()
158 .with_experiment(exp)
159 .scans()
160 .with_scan(scn)
161 .build()
162 },
163 Resource {
164 project: Some(pjt),
165 subject: Some(sbj),
166 experiment: Some(exp),
167 ..
168 } => {
169 self
170 .version()
171 .project_data()
172 .with_id(pjt)
173 .subjects()
174 .with_subject(sbj)
175 .experiments()
176 .with_experiment(exp)
177 .build()
178 },
179 Resource {
180 project: Some(pjt),
181 subject: Some(sbj),
182 ..
183 } => {
184 self
185 .version()
186 .project_data()
187 .with_id(pjt)
188 .subjects()
189 .with_subject(sbj)
190 .build()
191 },
192 Resource {
193 project: Some(pjt),
194 ..
195 } => {
196 self
197 .version()
198 .project_data()
199 .with_id(pjt)
200 .build()
201 },
202 _ => return Err(CrudError::IdentifierRequired("any identifiers".into()).into())
203 }?;
204 let uri = ResourcesUriBuilder::default().with_parent(&uri);
205 let uri = match &model {
206 Resource { collection: Some(c), name: Some(n), .. } => {
207 uri.with_resource(c).with_file(n)
208 },
209 Resource { collection: Some(c), .. } => {
210 uri.with_resource(c)
211 },
212 _ => uri,
213 };
214
215 self.delete(&uri).await?.send().await?;
216 Ok(model)
217 }
218}