1use std::{
2 collections::HashMap,
3 ops::{Deref, DerefMut},
4};
5
6
7use super::{
8 DataProcessing, FileDescription, InstrumentConfiguration, MassSpectrometryRun, Sample, Software, ScanSettings
9};
10
11pub trait MSDataFileMetadata {
13 fn data_processings(&self) -> &Vec<DataProcessing>;
16 fn instrument_configurations(&self) -> &HashMap<u32, InstrumentConfiguration>;
19 fn file_description(&self) -> &FileDescription;
22 fn softwares(&self) -> &Vec<Software>;
25
26 fn samples(&self) -> &Vec<Sample>;
29
30 fn scan_settings(&self) -> Option<&Vec<ScanSettings>> {
36 None
37 }
38
39 fn data_processings_mut(&mut self) -> &mut Vec<DataProcessing>;
41 fn instrument_configurations_mut(&mut self) -> &mut HashMap<u32, InstrumentConfiguration>;
43 fn file_description_mut(&mut self) -> &mut FileDescription;
46 fn softwares_mut(&mut self) -> &mut Vec<Software>;
48 fn samples_mut(&mut self) -> &mut Vec<Sample>;
49
50 fn scan_settings_mut(&mut self) -> Option<&mut Vec<ScanSettings>> {
53 None
54 }
55
56 fn copy_metadata_from(&mut self, source: &impl MSDataFileMetadata)
59 where
60 Self: Sized,
61 {
62 *self.data_processings_mut() = source.data_processings().clone();
63 *self.instrument_configurations_mut() = source.instrument_configurations().clone();
64 *self.file_description_mut() = source.file_description().clone();
65 *self.softwares_mut() = source.softwares().clone();
66 *self.samples_mut() = source.samples().clone();
67 self.set_spectrum_count_hint(source.spectrum_count_hint());
68
69 if let Some(settings) = source.scan_settings() {
70 match self.scan_settings_mut() {
71 Some(mine) => *mine = settings.clone(),
72 None => {
73 log::debug!("Cannot store scan settings on this type of data file");
74 }
75 }
76 }
77
78 match source.run_description() {
79 Some(run) => {
80 let desc = self.run_description_mut();
81 if let Some(r) = desc {
82 *r = run.clone();
83 };
84 }
85 None => {
86 let mut desc = self.run_description_mut();
87 desc.take();
88 }
89 }
90 }
91
92 fn spectrum_count_hint(&self) -> Option<u64> {
94 None
95 }
96
97 fn set_spectrum_count_hint(&mut self, _value: Option<u64>) {}
98
99 fn run_description(&self) -> Option<&MassSpectrometryRun> {
101 None
102 }
103
104 fn run_description_mut(&mut self) -> Option<&mut MassSpectrometryRun> {
106 None
107 }
108
109 fn source_file_name(&self) -> Option<&str> {
111 self.file_description()
112 .source_files
113 .first()
114 .map(|s| s.name.as_str())
115 }
116}
117
118#[derive(Debug, Default, Clone)]
121pub struct FileMetadataConfig {
122 pub(crate) file_description: FileDescription,
125
126 pub(crate) instrument_configurations: HashMap<u32, InstrumentConfiguration>,
129
130 pub(crate) softwares: Vec<Software>,
133
134 pub(crate) samples: Vec<Sample>,
135
136 pub(crate) scan_settings: Vec<ScanSettings>,
137
138 pub(crate) data_processings: Vec<DataProcessing>,
141
142 pub(crate) run: MassSpectrometryRun,
144 pub(crate) num_spectra: Option<u64>,
145}
146
147impl FileMetadataConfig {
148 #[allow(clippy::too_many_arguments)]
149 pub fn new(
150 file_description: FileDescription,
151 instrument_configurations: HashMap<u32, InstrumentConfiguration>,
152 softwares: Vec<Software>,
153 samples: Vec<Sample>,
154 scan_settings: Vec<ScanSettings>,
155 data_processings: Vec<DataProcessing>,
156 run: MassSpectrometryRun,
157 num_spectra: Option<u64>,
158 ) -> Self {
159 Self {
160 file_description,
161 instrument_configurations,
162 softwares,
163 samples,
164 scan_settings,
165 data_processings,
166 run,
167 num_spectra,
168 }
169 }
170}
171
172impl<T> From<&T> for FileMetadataConfig
173where
174 T: MSDataFileMetadata,
175{
176 fn from(value: &T) -> Self {
177 let mut this = Self::default();
178 this.copy_metadata_from(value);
179 this
180 }
181}
182
183impl MSDataFileMetadata for FileMetadataConfig {
184 crate::impl_metadata_trait!();
185
186 fn scan_settings(&self) -> Option<&Vec<ScanSettings>> {
187 Some(&self.scan_settings)
188 }
189
190 fn scan_settings_mut(&mut self) -> Option<&mut Vec<ScanSettings>> {
191 Some(&mut self.scan_settings)
192 }
193
194 fn run_description(&self) -> Option<&MassSpectrometryRun> {
195 Some(&self.run)
196 }
197
198 fn run_description_mut(&mut self) -> Option<&mut MassSpectrometryRun> {
199 Some(&mut self.run)
200 }
201
202 fn set_spectrum_count_hint(&mut self, _value: Option<u64>) {
203 self.num_spectra = _value
204 }
205
206 fn spectrum_count_hint(&self) -> Option<u64> {
207 self.num_spectra
208 }
209}
210
211#[macro_export]
212macro_rules! impl_metadata_trait {
216 (extended) => {
217 $crate::impl_metadata_trait();
218
219 fn spectrum_count_hint(&self) -> Option<u64> {
220 self.num_spectra
221 }
222
223 fn run_description(&self) -> Option<&$crate::MassSpectrometryRun> {
224 Some(&self.run)
225 }
226
227 fn run_description_mut(&mut self) -> Option<&mut $crate::MassSpectrometryRun> {
228 Some(&mut self.run)
229 }
230 };
231 () => {
232 fn data_processings(&self) -> &Vec<$crate::DataProcessing> {
233 &self.data_processings
234 }
235
236 fn instrument_configurations(
237 &self,
238 ) -> &std::collections::HashMap<u32, $crate::InstrumentConfiguration> {
239 &self.instrument_configurations
240 }
241 fn file_description(&self) -> &$crate::FileDescription {
242 &self.file_description
243 }
244 fn softwares(&self) -> &Vec<$crate::Software> {
245 &self.softwares
246 }
247
248 fn data_processings_mut(&mut self) -> &mut Vec<$crate::DataProcessing> {
249 &mut self.data_processings
250 }
251
252 fn instrument_configurations_mut(
253 &mut self,
254 ) -> &mut std::collections::HashMap<u32, $crate::InstrumentConfiguration> {
255 &mut self.instrument_configurations
256 }
257
258 fn file_description_mut(&mut self) -> &mut $crate::FileDescription {
259 &mut self.file_description
260 }
261
262 fn softwares_mut(&mut self) -> &mut Vec<$crate::Software> {
263 &mut self.softwares
264 }
265
266 fn samples(&self) -> &Vec<$crate::Sample> {
267 &self.samples
268 }
269
270 fn samples_mut(&mut self) -> &mut Vec<$crate::Sample> {
271 &mut self.samples
272 }
273 };
274}
275
276#[macro_export]
277macro_rules! delegate_impl_metadata_trait {
280
281 (expr, $self:ident => $impl:tt, &mut => $mut_impl:tt) => {
282
283 fn data_processings(&self) -> &Vec<$crate::DataProcessing> {
284 let $self = self;
285 let step = $impl;
286 step.data_processings()
287 }
288
289 fn instrument_configurations(&self) -> &std::collections::HashMap<u32, $crate::InstrumentConfiguration> {
290 let $self = self;
291 let step = $impl;
292 step.instrument_configurations()
293 }
294
295 fn file_description(&self) -> &$crate::FileDescription {
296 let $self = self;
297 let step = $impl;
298 step.file_description()
299 }
300
301 fn softwares(&self) -> &Vec<$crate::Software> {
302 let $self = self;
303 let step = $impl;
304 step.softwares()
305 }
306
307 fn samples(&self) -> &Vec<$crate::Sample> {
308 let $self = self;
309 let step = $impl;
310 step.samples()
311 }
312
313 fn data_processings_mut(&mut self) -> &mut Vec<$crate::DataProcessing> {
314 let $self = self;
315 let step = $mut_impl;
316 step.data_processings_mut()
317 }
318
319 fn instrument_configurations_mut(&mut self) -> &mut std::collections::HashMap<u32, $crate::InstrumentConfiguration> {
320 let $self = self;
321 let step = $mut_impl;
322 step.instrument_configurations_mut()
323 }
324
325 fn file_description_mut(&mut self) -> &mut $crate::FileDescription {
326 let $self = self;
327 let step = $mut_impl;
328 step.file_description_mut()
329 }
330
331 fn softwares_mut(&mut self) -> &mut Vec<$crate::Software> {
332 let $self = self;
333 let step = $mut_impl;
334 step.softwares_mut()
335 }
336
337 fn samples_mut(&mut self) -> &mut Vec<$crate::Sample> {
338 let $self = self;
339 let step = $mut_impl;
340 step.samples_mut()
341 }
342
343 fn spectrum_count_hint(&self) -> Option<u64> {
344 let $self = self;
345 let step = $impl;
346 step.spectrum_count_hint()
347 }
348
349 fn run_description(&self) -> Option<&$crate::MassSpectrometryRun> {
350 let $self = self;
351 let step = $impl;
352 step.run_description()
353 }
354
355 fn run_description_mut(&mut self) -> Option<&mut $crate::MassSpectrometryRun> {
356 let $self = self;
357 let step = $mut_impl;
358 step.run_description_mut()
359 }
360
361 fn source_file_name(&self) -> Option<&str> {
362 let $self = self;
363 let step = $impl;
364 step.source_file_name()
365 }
366
367 fn scan_settings(&self) -> Option<&Vec<$crate::ScanSettings>> {
368 let $self = self;
369 let step = $impl;
370 step.scan_settings()
371 }
372
373 fn scan_settings_mut(&mut self) -> Option<&mut Vec<$crate::ScanSettings>> {
374 let $self = self;
375 let step = $mut_impl;
376 step.scan_settings_mut()
377 }
378 };
379 ($src:tt, extended) => {
380 $crate::delegate_impl_metadata_trait($src);
381 };
382 ($src:tt) => {
383 $crate::delegate_impl_metadata_trait!(expr, this => { &this.$src }, &mut => { &mut this.$src });
384 };
385}
386
387impl<T: MSDataFileMetadata> MSDataFileMetadata for Box<T> {
388 delegate_impl_metadata_trait!(expr, x => { x.deref() }, &mut => { x.deref_mut() });
389}
390
391impl<T: MSDataFileMetadata> MSDataFileMetadata for std::sync::Arc<T> {
394 delegate_impl_metadata_trait!(expr, x => { x.deref() }, &mut => { std::sync::Arc::get_mut(x).unwrap_or_else(|| panic!("Attempting to modify `MSDataFileMetadata` via a shared reference")) });
395}