1pub trait CoordinateSet: CoordinateMetadata {
9 fn len(&self) -> usize;
11
12 fn dim(&self) -> usize;
15
16 fn get_coord(&self, index: usize) -> Coor4D;
18
19 fn set_coord(&mut self, index: usize, value: &Coor4D);
21
22 fn is_empty(&self) -> bool {
24 self.len() == 0
25 }
26
27 fn set_xy(&mut self, index: usize, x: f64, y: f64) {
33 let mut coord = self.get_coord(index);
34 coord[0] = x;
35 coord[1] = y;
36 self.set_coord(index, &coord);
37 }
38
39 fn xy(&self, index: usize) -> (f64, f64) {
44 self.get_coord(index).xy()
45 }
46
47 fn set_xyz(&mut self, index: usize, x: f64, y: f64, z: f64) {
53 let mut coord = self.get_coord(index);
54 coord[0] = x;
55 coord[1] = y;
56 coord[2] = z;
57 self.set_coord(index, &coord);
58 }
59
60 fn xyz(&self, index: usize) -> (f64, f64, f64) {
65 self.get_coord(index).xyz()
66 }
67
68 fn set_xyzt(&mut self, index: usize, x: f64, y: f64, z: f64, t: f64) {
71 self.set_coord(index, &Coor4D([x, y, z, t]));
72 }
73
74 fn xyzt(&self, index: usize) -> (f64, f64, f64, f64) {
77 self.get_coord(index).xyzt()
78 }
79
80 fn stomp(&mut self) {
82 let nanny = Coor4D::nan();
83 for i in 0..self.len() {
84 self.set_coord(i, &nanny);
85 }
86 }
87}
88
89use super::*;
90
91macro_rules! length {
95 (array) => {
96 fn len(&self) -> usize {
97 N
98 }
99 };
100
101 (slice) => {
102 fn len(&self) -> usize {
103 (**self).len()
104 }
105 };
106
107 (vec) => {
108 fn len(&self) -> usize {
109 self.len()
110 }
111 };
112}
113
114macro_rules! coordinate_set_impl_2d_subset {
115 ($dim:expr, $len:ident) => {
116 length!($len);
117
118 fn dim(&self) -> usize {
119 $dim
120 }
121
122 fn xy(&self, index: usize) -> (f64, f64) {
123 self[index].xy()
124 }
125
126 fn set_xy(&mut self, index: usize, x: f64, y: f64) {
127 self[index].set_xy(x, y);
128 }
129 };
130}
131
132macro_rules! coordinate_set_impl_3d_subset {
133 ($dim:expr, $len:ident) => {
134 coordinate_set_impl_2d_subset!($dim, $len);
135
136 fn xyz(&self, index: usize) -> (f64, f64, f64) {
137 self[index].xyz()
138 }
139 fn set_xyz(&mut self, index: usize, x: f64, y: f64, z: f64) {
140 self[index].set_xyz(x, y, z);
141 }
142 };
143}
144
145macro_rules! coordinate_set_impl_for_coor2d {
165 ($kind:ident) => {
166 coordinate_set_impl_2d_subset!(2, $kind);
167
168 fn get_coord(&self, index: usize) -> Coor4D {
169 Coor4D([self[index][0], self[index][1], 0., f64::NAN])
170 }
171
172 fn set_coord(&mut self, index: usize, value: &Coor4D) {
173 self[index] = Coor2D([value[0], value[1]]);
174 }
175 };
176}
177
178impl<const N: usize> CoordinateSet for [Coor2D; N] {
179 coordinate_set_impl_for_coor2d!(array);
180}
181
182impl CoordinateSet for &mut [Coor2D] {
183 coordinate_set_impl_for_coor2d!(slice);
184}
185
186impl CoordinateSet for Vec<Coor2D> {
187 coordinate_set_impl_for_coor2d!(vec);
188}
189
190macro_rules! coordinate_set_impl_for_coor32 {
193 ($kind:ident) => {
194 coordinate_set_impl_2d_subset!(2, $kind);
195
196 fn get_coord(&self, index: usize) -> Coor4D {
197 Coor4D([self[index][0] as f64, self[index][1] as f64, 0., f64::NAN])
198 }
199
200 fn set_coord(&mut self, index: usize, value: &Coor4D) {
201 self[index] = Coor32([value[0] as f32, value[1] as f32]);
202 }
203 };
204}
205
206impl<const N: usize> CoordinateSet for [Coor32; N] {
207 coordinate_set_impl_for_coor32!(array);
208}
209
210impl CoordinateSet for &mut [Coor32] {
211 coordinate_set_impl_for_coor32!(slice);
212}
213
214impl CoordinateSet for Vec<Coor32> {
215 coordinate_set_impl_for_coor32!(vec);
216}
217
218macro_rules! coordinate_set_impl_for_coor3d {
221 ($kind:ident) => {
222 coordinate_set_impl_3d_subset!(3, $kind);
223
224 fn get_coord(&self, index: usize) -> Coor4D {
225 Coor4D([self[index][0], self[index][1], self[index][2], f64::NAN])
226 }
227
228 fn set_coord(&mut self, index: usize, value: &Coor4D) {
229 self[index] = Coor3D([value[0], value[1], value[2]]);
230 }
231 };
232}
233
234impl<const N: usize> CoordinateSet for [Coor3D; N] {
235 coordinate_set_impl_for_coor3d!(array);
236}
237
238impl CoordinateSet for &mut [Coor3D] {
239 coordinate_set_impl_for_coor3d!(slice);
240}
241
242impl CoordinateSet for Vec<Coor3D> {
243 coordinate_set_impl_for_coor3d!(vec);
244}
245
246macro_rules! coordinate_set_impl_for_coor4d {
249 ($kind:ident) => {
250 coordinate_set_impl_3d_subset!(4, $kind);
251
252 fn get_coord(&self, index: usize) -> Coor4D {
253 self[index]
254 }
255
256 fn set_coord(&mut self, index: usize, value: &Coor4D) {
257 self[index] = *value;
258 }
259
260 fn xyzt(&self, index: usize) -> (f64, f64, f64, f64) {
261 self[index].xyzt()
262 }
263
264 fn set_xyzt(&mut self, index: usize, x: f64, y: f64, z: f64, t: f64) {
265 self[index].set_xyzt(x, y, z, t);
266 }
267 };
268}
269
270impl<const N: usize> CoordinateSet for [Coor4D; N] {
271 coordinate_set_impl_for_coor4d!(array);
272}
273
274impl CoordinateSet for &mut [Coor4D] {
275 coordinate_set_impl_for_coor4d!(slice);
276}
277
278impl CoordinateSet for Vec<Coor4D> {
279 coordinate_set_impl_for_coor4d!(vec);
280}
281
282impl<T> CoordinateSet for (T, f64, f64)
286where
287 T: CoordinateSet,
288{
289 fn len(&self) -> usize {
290 self.0.len()
291 }
292 fn dim(&self) -> usize {
293 4
294 }
295 fn get_coord(&self, index: usize) -> Coor4D {
296 let c = self.0.get_coord(index);
297 Coor4D([c[0], c[1], self.1, self.2])
298 }
299 fn set_coord(&mut self, index: usize, value: &Coor4D) {
300 self.0.set_coord(index, value);
301 }
302}
303
304impl<T> CoordinateSet for (T, f64)
308where
309 T: CoordinateSet,
310{
311 fn len(&self) -> usize {
312 self.0.len()
313 }
314 fn dim(&self) -> usize {
315 4
316 }
317 fn get_coord(&self, index: usize) -> Coor4D {
318 let c = self.0.get_coord(index);
319 Coor4D([c[0], c[1], c[2], self.1])
320 }
321 fn set_coord(&mut self, index: usize, value: &Coor4D) {
322 self.0.set_coord(index, value);
323 }
324}
325
326impl MdIdentifier {
328 pub fn new() -> Self {
329 MdIdentifier(uuid::Uuid::new_v4())
330 }
331}
332impl Default for MdIdentifier {
333 fn default() -> Self {
334 MdIdentifier(uuid::Uuid::new_v4())
335 }
336}
337
338impl DataEpoch {
339 pub fn new() -> Self {
340 DataEpoch(f64::NAN)
341 }
342}
343
344#[cfg(test)]
347mod tests {
348 use super::*;
351 #[test]
353 fn array() {
354 let mut operands = crate::test_data::coor4d();
355 assert_eq!(operands.len(), 2);
356 assert!(!operands.is_empty());
357
358 let cph = operands.get_coord(0);
359 assert_eq!(cph[0], 55.);
360 assert_eq!(cph[1], 12.);
361
362 let sth = operands.get_coord(1);
363 assert_eq!(sth[0], 59.);
364 assert_eq!(sth[1], 18.);
365
366 operands.set_coord(0, &sth);
368 let cph = operands.get_coord(0);
369 assert_eq!(cph[0], 59.);
370 assert_eq!(cph[1], 18.);
371 }
372
373 #[test]
375 fn vector() {
376 let mut operands = Vec::from(crate::test_data::coor2d());
377 assert_eq!(operands.len(), 2);
378 assert!(!operands.is_empty());
379
380 let cph = operands.get_coord(0);
381 assert_eq!(cph[0], 55.);
382 assert_eq!(cph[1], 12.);
383
384 let sth = operands.get_coord(1);
385 assert_eq!(sth[0], 59.);
386 assert_eq!(sth[1], 18.);
387
388 operands.set_coord(0, &sth);
390 let cph = operands.get_coord(0);
391 assert_eq!(cph[0], 59.);
392 assert_eq!(cph[1], 18.);
393 }
394
395 #[test]
397 fn angular() {
398 let operands = crate::test_data::coor2d();
399 let cph = operands.get_coord(0);
400
401 let cph = cph.to_radians();
406 assert_eq!(cph[0], operands.get_coord(0).to_radians()[0]);
407 assert_eq!(cph[1], operands.get_coord(0).to_radians()[1]);
408
409 assert_eq!(
410 cph[0].to_degrees() * 3600.,
411 operands.get_coord(0).to_radians().to_arcsec()[0]
412 );
413 assert_eq!(
414 cph[1].to_degrees() * 3600.,
415 operands.get_coord(0).to_radians().to_arcsec()[1]
416 );
417 }
418
419 #[test]
420 fn setting_and_getting_as_f64() {
421 let first = Coor4D([11., 12., 13., 14.]);
422 let second = Coor4D([21., 22., 23., 24.]);
423 let mut operands = Vec::from([first, second]);
424 let (x, y) = operands.xy(0);
425 assert_eq!((x, y), (11., 12.));
426 let (x, y) = operands.xy(1);
427 assert_eq!((x, y), (21., 22.));
428 operands.set_xy(0, x, y);
429 let (x, y) = operands.xy(0);
430 assert_eq!((x, y), (21., 22.));
431
432 let mut operands = Vec::from([first, second]);
433 let (x, y, z) = operands.xyz(0);
434 assert_eq!((x, y, z), (11., 12., 13.));
435 let (x, y, z) = operands.xyz(1);
436 assert_eq!((x, y, z), (21., 22., 23.));
437 operands.set_xyz(0, x, y, z);
438 let (x, y, z) = operands.xyz(0);
439 assert_eq!((x, y, z), (21., 22., 23.));
440
441 let mut operands = Vec::from([first, second]);
442 let (x, y, z, t) = operands.xyzt(0);
443 assert_eq!((x, y, z, t), (11., 12., 13., 14.));
444 let (x, y, z, t) = operands.xyzt(1);
445 assert_eq!((x, y, z, t), (21., 22., 23., 24.));
446 operands.set_xyzt(0, x, y, z, t);
447 let (x, y, z, t) = operands.xyzt(0);
448 assert_eq!((x, y, z, t), (21., 22., 23., 24.));
449 }
450}