1use crate::error::DmapError;
3use indexmap::IndexMap;
4use ndarray::ArrayD;
5use paste::paste;
6use std::cmp::PartialEq;
7use std::fmt::{Display, Formatter};
8use zerocopy::{AsBytes, ByteOrder, FromBytes, LittleEndian};
9
10type Result<T> = std::result::Result<T, DmapError>;
11
12pub struct Fields<'a> {
14 pub all_fields: Vec<&'a str>,
16 pub scalars_required: Vec<(&'a str, Type)>,
18 pub scalars_optional: Vec<(&'a str, Type)>,
20 pub vectors_required: Vec<(&'a str, Type)>,
22 pub vectors_optional: Vec<(&'a str, Type)>,
24 pub vector_dim_groups: Vec<Vec<&'a str>>,
26 pub data_fields: Vec<&'a str>,
28}
29
30#[derive(Debug, PartialEq, Clone)]
34pub enum Type {
35 Char,
36 Short,
37 Int,
38 Long,
39 Uchar,
40 Ushort,
41 Uint,
42 Ulong,
43 Float,
44 Double,
45 String,
46}
47impl Display for Type {
48 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
49 match self {
50 Self::Char => write!(f, "CHAR"),
51 Self::Short => write!(f, "SHORT"),
52 Self::Int => write!(f, "INT"),
53 Self::Float => write!(f, "FLOAT"),
54 Self::Double => write!(f, "DOUBLE"),
55 Self::String => write!(f, "STRING"),
56 Self::Long => write!(f, "LONG"),
57 Self::Uchar => write!(f, "UCHAR"),
58 Self::Ushort => write!(f, "USHORT"),
59 Self::Uint => write!(f, "UINT"),
60 Self::Ulong => write!(f, "ULONG"),
61 }
62 }
63}
64impl Type {
65 pub(crate) fn from_key(key: i8) -> Result<Self> {
68 let data = match key {
69 1 => Self::Char,
70 2 => Self::Short,
71 3 => Self::Int,
72 10 => Self::Long,
73 16 => Self::Uchar,
74 17 => Self::Ushort,
75 18 => Self::Uint,
76 19 => Self::Ulong,
77 4 => Self::Float,
78 8 => Self::Double,
79 9 => Self::String,
80 x => Err(DmapError::InvalidKey(x))?,
81 };
82 Ok(data)
83 }
84 pub(crate) fn key(&self) -> i8 {
86 match self {
87 Self::Char => 1,
88 Self::Short => 2,
89 Self::Int => 3,
90 Self::Long => 10,
91 Self::Uchar => 16,
92 Self::Ushort => 17,
93 Self::Uint => 18,
94 Self::Ulong => 19,
95 Self::Float => 4,
96 Self::Double => 8,
97 Self::String => 9,
98 }
99 }
100 pub fn size(&self) -> usize {
102 match self {
103 Self::Char => 1,
104 Self::Short => 2,
105 Self::Int => 4,
106 Self::Long => 8,
107 Self::Uchar => 1,
108 Self::Ushort => 2,
109 Self::Uint => 4,
110 Self::Ulong => 8,
111 Self::Float => 4,
112 Self::Double => 8,
113 Self::String => 0,
114 }
115 }
116}
117
118#[derive(Debug, Clone, PartialEq)]
121#[repr(C)]
122pub enum DmapScalar {
123 Char(i8),
124 Short(i16),
125 Int(i32),
126 Long(i64),
127 Uchar(u8),
128 Ushort(u16),
129 Uint(u32),
130 Ulong(u64),
131 Float(f32),
132 Double(f64),
133 String(String),
134}
135impl DmapScalar {
136 pub(crate) fn get_type(&self) -> Type {
138 match self {
139 Self::Char(_) => Type::Char,
140 Self::Short(_) => Type::Short,
141 Self::Int(_) => Type::Int,
142 Self::Long(_) => Type::Long,
143 Self::Uchar(_) => Type::Uchar,
144 Self::Ushort(_) => Type::Ushort,
145 Self::Uint(_) => Type::Uint,
146 Self::Ulong(_) => Type::Ulong,
147 Self::Float(_) => Type::Float,
148 Self::Double(_) => Type::Double,
149 Self::String(_) => Type::String,
150 }
151 }
152
153 pub(crate) fn cast_as(&self, new_type: &Type) -> Result<Self> {
155 match new_type {
156 Type::Char => Ok(Self::Char(i8::try_from(self.clone())?)),
157 Type::Short => Ok(Self::Short(i16::try_from(self.clone())?)),
158 Type::Int => Ok(Self::Int(i32::try_from(self.clone())?)),
159 Type::Long => Ok(Self::Long(i64::try_from(self.clone())?)),
160 Type::Uchar => Ok(Self::Uchar(u8::try_from(self.clone())?)),
161 Type::Ushort => Ok(Self::Ushort(u16::try_from(self.clone())?)),
162 Type::Uint => Ok(Self::Uint(u32::try_from(self.clone())?)),
163 Type::Ulong => Ok(Self::Ulong(u64::try_from(self.clone())?)),
164 Type::Float => Ok(Self::Float(f32::try_from(self.clone())?)),
165 Type::Double => Ok(Self::Double(f64::try_from(self.clone())?)),
166 Type::String => Err(DmapError::InvalidScalar(
167 "Unable to cast value to String".to_string(),
168 )),
169 }
170 }
171 pub(crate) fn as_bytes(&self) -> Vec<u8> {
173 let mut bytes: Vec<u8> = DmapType::as_bytes(&self.get_type().key()).to_vec();
174 let mut data_bytes: Vec<u8> = match self {
175 Self::Char(x) => DmapType::as_bytes(x),
176 Self::Short(x) => DmapType::as_bytes(x),
177 Self::Int(x) => DmapType::as_bytes(x),
178 Self::Long(x) => DmapType::as_bytes(x),
179 Self::Uchar(x) => DmapType::as_bytes(x),
180 Self::Ushort(x) => DmapType::as_bytes(x),
181 Self::Uint(x) => DmapType::as_bytes(x),
182 Self::Ulong(x) => DmapType::as_bytes(x),
183 Self::Float(x) => DmapType::as_bytes(x),
184 Self::Double(x) => DmapType::as_bytes(x),
185 Self::String(x) => DmapType::as_bytes(x),
186 };
187 bytes.append(&mut data_bytes);
188 bytes
189 }
190}
191impl Display for DmapScalar {
192 fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
193 match self {
194 Self::Char(x) => write!(f, "CHAR {x}"),
195 Self::Short(x) => write!(f, "SHORT {x}"),
196 Self::Int(x) => write!(f, "INT {x}"),
197 Self::Float(x) => write!(f, "FLOAT {x}"),
198 Self::Double(x) => write!(f, "DOUBLE {x}"),
199 Self::String(x) => write!(f, "STRING {x}"),
200 Self::Long(x) => write!(f, "LONG {x}"),
201 Self::Uchar(x) => write!(f, "UCHAR {x}"),
202 Self::Ushort(x) => write!(f, "USHORT {x}"),
203 Self::Uint(x) => write!(f, "UINT {x}"),
204 Self::Ulong(x) => write!(f, "ULONG {x}"),
205 }
206 }
207}
208
209macro_rules! vec_to_bytes {
210 ($bytes:ident, $x:ident) => {{
211 $bytes.extend(($x.ndim() as i32).to_le_bytes());
212 for &dim in $x.shape().iter().rev() {
213 $bytes.extend((dim as i32).to_le_bytes());
214 }
215 for y in $x.iter() {
216 $bytes.append(&mut DmapType::as_bytes(y).to_vec());
217 }
218 }};
219}
220
221#[derive(Clone, Debug, PartialEq)]
223pub enum DmapVec {
224 Char(ArrayD<i8>),
225 Short(ArrayD<i16>),
226 Int(ArrayD<i32>),
227 Long(ArrayD<i64>),
228 Uchar(ArrayD<u8>),
229 Ushort(ArrayD<u16>),
230 Uint(ArrayD<u32>),
231 Ulong(ArrayD<u64>),
232 Float(ArrayD<f32>),
233 Double(ArrayD<f64>),
234}
235impl DmapVec {
236 #[inline]
238 pub(crate) fn get_type(&self) -> Type {
239 match self {
240 DmapVec::Char(_) => Type::Char,
241 DmapVec::Short(_) => Type::Short,
242 DmapVec::Int(_) => Type::Int,
243 DmapVec::Long(_) => Type::Long,
244 DmapVec::Uchar(_) => Type::Uchar,
245 DmapVec::Ushort(_) => Type::Ushort,
246 DmapVec::Uint(_) => Type::Uint,
247 DmapVec::Ulong(_) => Type::Ulong,
248 DmapVec::Float(_) => Type::Float,
249 DmapVec::Double(_) => Type::Double,
250 }
251 }
252 #[inline]
254 pub(crate) fn as_bytes(&self) -> Vec<u8> {
255 let mut bytes: Vec<u8> = DmapType::as_bytes(&self.get_type().key()).to_vec();
256 match self {
257 DmapVec::Char(x) => vec_to_bytes!(bytes, x),
258 DmapVec::Short(x) => vec_to_bytes!(bytes, x),
259 DmapVec::Int(x) => vec_to_bytes!(bytes, x),
260 DmapVec::Long(x) => vec_to_bytes!(bytes, x),
261 DmapVec::Uchar(x) => vec_to_bytes!(bytes, x),
262 DmapVec::Ushort(x) => vec_to_bytes!(bytes, x),
263 DmapVec::Uint(x) => vec_to_bytes!(bytes, x),
264 DmapVec::Ulong(x) => vec_to_bytes!(bytes, x),
265 DmapVec::Float(x) => vec_to_bytes!(bytes, x),
266 DmapVec::Double(x) => vec_to_bytes!(bytes, x),
267 };
268 bytes
269 }
270
271 #[must_use]
284 pub fn shape(&self) -> &[usize] {
285 match self {
286 DmapVec::Char(x) => x.shape(),
287 DmapVec::Short(x) => x.shape(),
288 DmapVec::Int(x) => x.shape(),
289 DmapVec::Long(x) => x.shape(),
290 DmapVec::Uchar(x) => x.shape(),
291 DmapVec::Ushort(x) => x.shape(),
292 DmapVec::Uint(x) => x.shape(),
293 DmapVec::Ulong(x) => x.shape(),
294 DmapVec::Float(x) => x.shape(),
295 DmapVec::Double(x) => x.shape(),
296 }
297 }
298}
299
300macro_rules! vec_impls {
306 ($type:ty, $enum_var:path) => {
307 impl From<$type> for DmapVec {
308 #[inline]
309 fn from(value: $type) -> Self {
310 $enum_var(value)
311 }
312 }
313
314 impl TryFrom<DmapVec> for $type {
315 type Error = DmapError;
316
317 fn try_from(value: DmapVec) -> std::result::Result<Self, Self::Error> {
318 if let $enum_var(x) = value {
319 Ok(x)
320 } else {
321 Err(DmapError::InvalidVector(format!(
322 "Cannot convert to {}",
323 stringify!($type)
324 )))
325 }
326 }
327 }
328
329 impl From<$type> for DmapField {
330 #[inline]
331 fn from(value: $type) -> Self {
332 DmapField::Vector($enum_var(value))
333 }
334 }
335
336 impl TryFrom<DmapField> for $type {
337 type Error = DmapError;
338
339 fn try_from(value: DmapField) -> std::result::Result<Self, Self::Error> {
340 match value {
341 DmapField::Vector(x) => x.try_into(),
342 _ => Err(Self::Error::InvalidVector(format!(
343 "Cannot interpret as {}",
344 stringify!($type)
345 ))),
346 }
347 }
348 }
349 };
350}
351
352vec_impls!(ArrayD<i8>, DmapVec::Char);
353vec_impls!(ArrayD<i16>, DmapVec::Short);
354vec_impls!(ArrayD<i32>, DmapVec::Int);
355vec_impls!(ArrayD<i64>, DmapVec::Long);
356vec_impls!(ArrayD<u8>, DmapVec::Uchar);
357vec_impls!(ArrayD<u16>, DmapVec::Ushort);
358vec_impls!(ArrayD<u32>, DmapVec::Uint);
359vec_impls!(ArrayD<u64>, DmapVec::Ulong);
360vec_impls!(ArrayD<f32>, DmapVec::Float);
361vec_impls!(ArrayD<f64>, DmapVec::Double);
362
363#[derive(Debug, Clone, PartialEq)]
368#[repr(C)]
369pub enum DmapField {
370 Vector(DmapVec),
371 Scalar(DmapScalar),
372}
373impl DmapField {
374 #[inline]
376 #[must_use]
377 pub fn as_bytes(&self) -> Vec<u8> {
378 match self {
379 Self::Scalar(x) => x.as_bytes(),
380 Self::Vector(x) => x.as_bytes(),
381 }
382 }
383}
384
385macro_rules! scalar_impls {
392 ($type:ty, $enum_var:path, $type_var:path) => {
393 impl From<$type> for DmapField {
394 fn from(value: $type) -> Self {
395 DmapField::Scalar($enum_var(value))
396 }
397 }
398 impl TryFrom<DmapField> for $type {
399 type Error = DmapError;
400
401 fn try_from(value: DmapField) -> std::result::Result<Self, Self::Error> {
402 match value {
403 DmapField::Scalar(x) => x.try_into(),
404 _ => Err(Self::Error::InvalidScalar(format!(
405 "Cannot interpret {value:?} as {}",
406 stringify!($type)
407 ))),
408 }
409 }
410 }
411 };
412}
413
414scalar_impls!(i8, DmapScalar::Char, Type::Char);
415scalar_impls!(i16, DmapScalar::Short, Type::Short);
416scalar_impls!(i32, DmapScalar::Int, Type::Int);
417scalar_impls!(i64, DmapScalar::Long, Type::Long);
418scalar_impls!(u8, DmapScalar::Uchar, Type::Uchar);
419scalar_impls!(u16, DmapScalar::Ushort, Type::Ushort);
420scalar_impls!(u32, DmapScalar::Uint, Type::Uint);
421scalar_impls!(u64, DmapScalar::Ulong, Type::Ulong);
422scalar_impls!(f32, DmapScalar::Float, Type::Float);
423scalar_impls!(f64, DmapScalar::Double, Type::Double);
424scalar_impls!(String, DmapScalar::String, Type::String);
425
426pub trait DmapType: std::fmt::Debug {
428 fn size() -> usize
430 where
431 Self: Sized;
432 fn as_bytes(&self) -> Vec<u8>;
434 fn from_bytes(bytes: &[u8]) -> Result<Self>
439 where
440 Self: Sized;
441 fn dmap_type() -> Type;
443}
444
445macro_rules! type_impls {
448 ($type:ty, $enum_var:path, 1) => {
450 impl DmapType for $type {
451 #[inline]
452 fn size() -> usize { 1 }
453
454 #[inline]
455 fn as_bytes(&self) -> Vec<u8> {
456 AsBytes::as_bytes(self).to_vec()
457 }
458
459 #[inline]
460 fn from_bytes(bytes: &[u8]) -> Result<Self>
461 where
462 Self: Sized,
463 {
464 Self::read_from(bytes).ok_or(DmapError::CorruptStream("Unable to interpret bytes"))
465 }
466
467 #[inline]
468 fn dmap_type() -> Type { $enum_var }
469 }
470 };
471 ($type:ty, $enum_var:path, $num_bytes:expr) => {
473 paste! {
474 impl DmapType for $type {
475 #[inline]
476 fn size() -> usize { $num_bytes }
477
478 #[inline]
479 fn as_bytes(&self) -> Vec<u8> {
480 let mut bytes = [0; $num_bytes];
481 LittleEndian::[< write_ $type >](&mut bytes, *self);
482 bytes.to_vec()
483 }
484
485 #[inline]
486 fn from_bytes(bytes: &[u8]) -> Result<Self>
487 where
488 Self: Sized,
489 {
490 Self::read_from(bytes).ok_or(DmapError::CorruptStream("Unable to interpret bytes"))
491 }
492
493 #[inline]
494 fn dmap_type() -> Type { $enum_var }
495 }
496 }
497 }
498}
499
500type_impls!(i8, Type::Char, 1);
501type_impls!(i16, Type::Short, 2);
502type_impls!(i32, Type::Int, 4);
503type_impls!(i64, Type::Long, 8);
504type_impls!(u8, Type::Uchar, 1);
505type_impls!(u16, Type::Ushort, 2);
506type_impls!(u32, Type::Uint, 4);
507type_impls!(u64, Type::Ulong, 8);
508type_impls!(f32, Type::Float, 4);
509type_impls!(f64, Type::Double, 8);
510
511impl DmapType for String {
513 #[inline]
514 fn size() -> usize {
515 0
516 }
517
518 #[inline]
519 fn as_bytes(&self) -> Vec<u8> {
520 let mut bytes = self.as_bytes().to_vec();
521 bytes.push(0); bytes
523 }
524
525 #[inline]
526 fn from_bytes(bytes: &[u8]) -> Result<Self> {
527 let data = String::from_utf8(bytes.to_owned())
528 .map_err(|_| DmapError::InvalidScalar("Cannot convert bytes to String".to_string()))?;
529 Ok(data.trim_end_matches(char::from(0)).to_string())
530 }
531
532 #[inline]
533 fn dmap_type() -> Type {
534 Type::String
535 }
536}
537
538impl TryFrom<DmapScalar> for u8 {
539 type Error = DmapError;
540 fn try_from(value: DmapScalar) -> std::result::Result<Self, Self::Error> {
541 match value {
542 DmapScalar::Char(x) => Ok(u8::try_from(x)?),
543 DmapScalar::Short(x) => Ok(u8::try_from(x)?),
544 DmapScalar::Int(x) => Ok(u8::try_from(x)?),
545 DmapScalar::Long(x) => Ok(u8::try_from(x)?),
546 DmapScalar::Uchar(x) => Ok(x),
547 DmapScalar::Ushort(x) => Ok(u8::try_from(x)?),
548 DmapScalar::Uint(x) => Ok(u8::try_from(x)?),
549 DmapScalar::Ulong(x) => Ok(u8::try_from(x)?),
550 DmapScalar::Float(x) => Err(DmapError::InvalidScalar(format!(
551 "Unable to convert {x}_f32 to u8"
552 ))),
553 DmapScalar::Double(x) => Err(DmapError::InvalidScalar(format!(
554 "Unable to convert {x}_f64 to u8"
555 ))),
556 DmapScalar::String(x) => Err(DmapError::InvalidScalar(format!(
557 "Unable to convert {x} to u8"
558 ))),
559 }
560 }
561}
562impl TryFrom<DmapScalar> for u16 {
563 type Error = DmapError;
564 fn try_from(value: DmapScalar) -> std::result::Result<Self, Self::Error> {
565 match value {
566 DmapScalar::Char(x) => Ok(u16::try_from(x)?),
567 DmapScalar::Short(x) => Ok(u16::try_from(x)?),
568 DmapScalar::Int(x) => Ok(u16::try_from(x)?),
569 DmapScalar::Long(x) => Ok(u16::try_from(x)?),
570 DmapScalar::Uchar(x) => Ok(x as u16),
571 DmapScalar::Ushort(x) => Ok(x),
572 DmapScalar::Uint(x) => Ok(u16::try_from(x)?),
573 DmapScalar::Ulong(x) => Ok(u16::try_from(x)?),
574 DmapScalar::Float(x) => Err(DmapError::InvalidScalar(format!(
575 "Unable to convert {x}_f32 to u16"
576 ))),
577 DmapScalar::Double(x) => Err(DmapError::InvalidScalar(format!(
578 "Unable to convert {x}_f64 to u16"
579 ))),
580 DmapScalar::String(x) => Err(DmapError::InvalidScalar(format!(
581 "Unable to convert {x} to u16"
582 ))),
583 }
584 }
585}
586impl TryFrom<DmapScalar> for u32 {
587 type Error = DmapError;
588 fn try_from(value: DmapScalar) -> std::result::Result<Self, Self::Error> {
589 match value {
590 DmapScalar::Char(x) => Ok(u32::try_from(x)?),
591 DmapScalar::Short(x) => Ok(u32::try_from(x)?),
592 DmapScalar::Int(x) => Ok(u32::try_from(x)?),
593 DmapScalar::Long(x) => Ok(u32::try_from(x)?),
594 DmapScalar::Uchar(x) => Ok(x as u32),
595 DmapScalar::Ushort(x) => Ok(x as u32),
596 DmapScalar::Uint(x) => Ok(x),
597 DmapScalar::Ulong(x) => Ok(u32::try_from(x)?),
598 DmapScalar::Float(x) => Err(DmapError::InvalidScalar(format!(
599 "Unable to convert {x}_f32 to u32"
600 ))),
601 DmapScalar::Double(x) => Err(DmapError::InvalidScalar(format!(
602 "Unable to convert {x}_f64 to u32"
603 ))),
604 DmapScalar::String(x) => Err(DmapError::InvalidScalar(format!(
605 "Unable to convert {x} to u32"
606 ))),
607 }
608 }
609}
610impl TryFrom<DmapScalar> for u64 {
611 type Error = DmapError;
612 fn try_from(value: DmapScalar) -> std::result::Result<Self, Self::Error> {
613 match value {
614 DmapScalar::Char(x) => Ok(u64::try_from(x)?),
615 DmapScalar::Short(x) => Ok(u64::try_from(x)?),
616 DmapScalar::Int(x) => Ok(u64::try_from(x)?),
617 DmapScalar::Long(x) => Ok(u64::try_from(x)?),
618 DmapScalar::Uchar(x) => Ok(x as u64),
619 DmapScalar::Ushort(x) => Ok(x as u64),
620 DmapScalar::Uint(x) => Ok(x as u64),
621 DmapScalar::Ulong(x) => Ok(x),
622 DmapScalar::Float(x) => Err(DmapError::InvalidScalar(format!(
623 "Unable to convert {x}_f32 to u64"
624 ))),
625 DmapScalar::Double(x) => Err(DmapError::InvalidScalar(format!(
626 "Unable to convert {x}_f64 to u64"
627 ))),
628 DmapScalar::String(x) => Err(DmapError::InvalidScalar(format!(
629 "Unable to convert {x} to u64"
630 ))),
631 }
632 }
633}
634impl TryFrom<DmapScalar> for i8 {
635 type Error = DmapError;
636 fn try_from(value: DmapScalar) -> std::result::Result<Self, Self::Error> {
637 match value {
638 DmapScalar::Char(x) => Ok(x),
639 DmapScalar::Short(x) => Ok(i8::try_from(x)?),
640 DmapScalar::Int(x) => Ok(i8::try_from(x)?),
641 DmapScalar::Long(x) => Ok(i8::try_from(x)?),
642 DmapScalar::Uchar(x) => Ok(i8::try_from(x)?),
643 DmapScalar::Ushort(x) => Ok(i8::try_from(x)?),
644 DmapScalar::Uint(x) => Ok(i8::try_from(x)?),
645 DmapScalar::Ulong(x) => Ok(i8::try_from(x)?),
646 DmapScalar::Float(x) => Err(DmapError::InvalidScalar(format!(
647 "Unable to convert {x}_f32 to i8"
648 ))),
649 DmapScalar::Double(x) => Err(DmapError::InvalidScalar(format!(
650 "Unable to convert {x}_f64 to i8"
651 ))),
652 DmapScalar::String(x) => Err(DmapError::InvalidScalar(format!(
653 "Unable to convert {x} to i8"
654 ))),
655 }
656 }
657}
658impl TryFrom<DmapScalar> for i16 {
659 type Error = DmapError;
660 fn try_from(value: DmapScalar) -> std::result::Result<Self, Self::Error> {
661 match value {
662 DmapScalar::Char(x) => Ok(x as i16),
663 DmapScalar::Short(x) => Ok(x),
664 DmapScalar::Int(x) => Ok(i16::try_from(x)?),
665 DmapScalar::Long(x) => Ok(i16::try_from(x)?),
666 DmapScalar::Uchar(x) => Ok(x as i16),
667 DmapScalar::Ushort(x) => Ok(i16::try_from(x)?),
668 DmapScalar::Uint(x) => Ok(i16::try_from(x)?),
669 DmapScalar::Ulong(x) => Ok(i16::try_from(x)?),
670 DmapScalar::Float(x) => Err(DmapError::InvalidScalar(format!(
671 "Unable to convert {x}_f32 to i16"
672 ))),
673 DmapScalar::Double(x) => Err(DmapError::InvalidScalar(format!(
674 "Unable to convert {x}_f64 to i16"
675 ))),
676 DmapScalar::String(x) => Err(DmapError::InvalidScalar(format!(
677 "Unable to convert {x} to i16"
678 ))),
679 }
680 }
681}
682impl TryFrom<DmapScalar> for i32 {
683 type Error = DmapError;
684 fn try_from(value: DmapScalar) -> std::result::Result<Self, Self::Error> {
685 match value {
686 DmapScalar::Char(x) => Ok(x as i32),
687 DmapScalar::Short(x) => Ok(x as i32),
688 DmapScalar::Int(x) => Ok(x),
689 DmapScalar::Long(x) => Ok(i32::try_from(x)?),
690 DmapScalar::Uchar(x) => Ok(x as i32),
691 DmapScalar::Ushort(x) => Ok(x as i32),
692 DmapScalar::Uint(x) => Ok(i32::try_from(x)?),
693 DmapScalar::Ulong(x) => Ok(i32::try_from(x)?),
694 DmapScalar::Float(x) => Err(DmapError::InvalidScalar(format!(
695 "Unable to convert {x}_f32 to i32"
696 ))),
697 DmapScalar::Double(x) => Err(DmapError::InvalidScalar(format!(
698 "Unable to convert {x}_f64 to i32"
699 ))),
700 DmapScalar::String(x) => Err(DmapError::InvalidScalar(format!(
701 "Unable to convert {x} to i32"
702 ))),
703 }
704 }
705}
706impl TryFrom<DmapScalar> for i64 {
707 type Error = DmapError;
708 fn try_from(value: DmapScalar) -> std::result::Result<Self, Self::Error> {
709 match value {
710 DmapScalar::Char(x) => Ok(x as i64),
711 DmapScalar::Short(x) => Ok(x as i64),
712 DmapScalar::Int(x) => Ok(x as i64),
713 DmapScalar::Long(x) => Ok(x),
714 DmapScalar::Uchar(x) => Ok(x as i64),
715 DmapScalar::Ushort(x) => Ok(x as i64),
716 DmapScalar::Uint(x) => Ok(x as i64),
717 DmapScalar::Ulong(x) => Ok(i64::try_from(x)?),
718 DmapScalar::Float(x) => Err(DmapError::InvalidScalar(format!(
719 "Unable to convert {x}_f32 to i64"
720 ))),
721 DmapScalar::Double(x) => Err(DmapError::InvalidScalar(format!(
722 "Unable to convert {x}_f64 to i64"
723 ))),
724 DmapScalar::String(x) => Err(DmapError::InvalidScalar(format!(
725 "Unable to convert {x} to i64"
726 ))),
727 }
728 }
729}
730impl TryFrom<DmapScalar> for f32 {
731 type Error = DmapError;
732 fn try_from(value: DmapScalar) -> std::result::Result<Self, Self::Error> {
733 match value {
734 DmapScalar::Char(x) => Ok(x as f32),
735 DmapScalar::Short(x) => Ok(x as f32),
736 DmapScalar::Int(x) => Ok(x as f32),
737 DmapScalar::Long(x) => Ok(x as f32),
738 DmapScalar::Uchar(x) => Ok(x as f32),
739 DmapScalar::Ushort(x) => Ok(x as f32),
740 DmapScalar::Uint(x) => Ok(x as f32),
741 DmapScalar::Ulong(x) => Ok(x as f32),
742 DmapScalar::Float(x) => Ok(x),
743 DmapScalar::Double(x) => Ok(x as f32),
744 DmapScalar::String(x) => Err(DmapError::InvalidScalar(format!(
745 "Unable to convert {x} to f32"
746 ))),
747 }
748 }
749}
750impl TryFrom<DmapScalar> for f64 {
751 type Error = DmapError;
752 fn try_from(value: DmapScalar) -> std::result::Result<Self, Self::Error> {
753 match value {
754 DmapScalar::Char(x) => Ok(x as f64),
755 DmapScalar::Short(x) => Ok(x as f64),
756 DmapScalar::Int(x) => Ok(x as f64),
757 DmapScalar::Long(x) => Ok(x as f64),
758 DmapScalar::Uchar(x) => Ok(x as f64),
759 DmapScalar::Ushort(x) => Ok(x as f64),
760 DmapScalar::Uint(x) => Ok(x as f64),
761 DmapScalar::Ulong(x) => Ok(x as f64),
762 DmapScalar::Float(x) => Ok(f64::from(x)),
763 DmapScalar::Double(x) => Ok(x),
764 DmapScalar::String(x) => Err(DmapError::InvalidScalar(format!(
765 "Unable to convert {x} to f64"
766 ))),
767 }
768 }
769}
770impl TryFrom<DmapScalar> for String {
771 type Error = DmapError;
772 fn try_from(value: DmapScalar) -> std::result::Result<Self, Self::Error> {
773 match value {
774 DmapScalar::String(x) => Ok(x),
775 x => Err(DmapError::InvalidScalar(format!(
776 "Unable to convert {x} to String"
777 ))),
778 }
779 }
780}
781
782pub fn check_scalar(
789 fields: &IndexMap<String, DmapField>,
790 name: &str,
791 expected_type: &Type,
792) -> Result<()> {
793 match fields.get(name) {
794 Some(DmapField::Scalar(data)) if data.get_type() == *expected_type => Ok(()),
795 Some(DmapField::Scalar(data)) => Err(DmapError::InvalidScalar(format!(
796 "{name} is of type {}, expected {}",
797 data.get_type(),
798 expected_type
799 ))),
800 Some(_) => Err(DmapError::InvalidScalar(format!(
801 "{name} is a vector field"
802 ))),
803 None => Err(DmapError::InvalidScalar(format!("{name} is not in record"))),
804 }
805}
806
807pub fn check_scalar_opt(
812 fields: &IndexMap<String, DmapField>,
813 name: &str,
814 expected_type: &Type,
815) -> Result<()> {
816 match fields.get(name) {
817 Some(DmapField::Scalar(data)) if data.get_type() == *expected_type => Ok(()),
818 Some(DmapField::Scalar(data)) => Err(DmapError::InvalidScalar(format!(
819 "{name} is of type {}, expected {}",
820 data.get_type(),
821 expected_type
822 ))),
823 Some(_) => Err(DmapError::InvalidScalar(format!(
824 "{name} is a vector field"
825 ))),
826 None => Ok(()),
827 }
828}
829
830pub fn check_vector(
837 fields: &IndexMap<String, DmapField>,
838 name: &str,
839 expected_type: &Type,
840) -> Result<()> {
841 match fields.get(name) {
842 Some(DmapField::Vector(data)) if data.get_type() != *expected_type => {
843 Err(DmapError::InvalidVector(format!(
844 "{name} is of type {}, expected {}",
845 data.get_type(),
846 expected_type
847 )))
848 }
849 Some(DmapField::Scalar(_)) => Err(DmapError::InvalidVector(format!(
850 "{name} is a scalar field"
851 ))),
852 None => Err(DmapError::InvalidVector(format!("{name} not in record"))),
853 _ => Ok(()),
854 }
855}
856
857pub fn check_vector_opt(
862 fields: &IndexMap<String, DmapField>,
863 name: &str,
864 expected_type: &Type,
865) -> Result<()> {
866 match fields.get(name) {
867 Some(DmapField::Vector(data)) if data.get_type() != *expected_type => {
868 Err(DmapError::InvalidVector(format!(
869 "{name} is of type {}, expected {}",
870 data.get_type(),
871 expected_type
872 )))
873 }
874 Some(DmapField::Scalar(_)) => Err(DmapError::InvalidVector(format!(
875 "{name} is a scalar field"
876 ))),
877 _ => Ok(()),
878 }
879}
880
881#[cfg(test)]
882mod tests {
883 use super::*;
884 use ndarray::array;
885
886 #[test]
887 fn dmaptype() -> Result<()> {
888 assert_eq!(i8::size(), 1);
889 assert_eq!(u8::size(), 1);
890 assert_eq!(i16::size(), 2);
891 assert_eq!(u16::size(), 2);
892 assert_eq!(i32::size(), 4);
893 assert_eq!(u32::size(), 4);
894 assert_eq!(f32::size(), 4);
895 assert_eq!(i64::size(), 8);
896 assert_eq!(u64::size(), 8);
897 assert_eq!(f64::size(), 8);
898
899 assert_eq!(i8::dmap_type(), Type::Char);
900 assert_eq!(u8::dmap_type(), Type::Uchar);
901 assert_eq!(i16::dmap_type(), Type::Short);
902 assert_eq!(u16::dmap_type(), Type::Ushort);
903 assert_eq!(i32::dmap_type(), Type::Int);
904 assert_eq!(u32::dmap_type(), Type::Uint);
905 assert_eq!(f32::dmap_type(), Type::Float);
906 assert_eq!(i64::dmap_type(), Type::Long);
907 assert_eq!(u64::dmap_type(), Type::Ulong);
908 assert_eq!(f64::dmap_type(), Type::Double);
909
910 assert_eq!(vec![1], DmapType::as_bytes(&i8::from_bytes(&[1])?));
911 assert_eq!(vec![1], DmapType::as_bytes(&u8::from_bytes(&[1])?));
912 assert_eq!(vec![1, 0], DmapType::as_bytes(&i16::from_bytes(&[1, 0])?));
913 assert_eq!(vec![1, 0], DmapType::as_bytes(&u16::from_bytes(&[1, 0])?));
914 assert_eq!(
915 vec![1, 0, 0, 0],
916 DmapType::as_bytes(&i32::from_bytes(&[1, 0, 0, 0])?)
917 );
918 assert_eq!(
919 vec![1, 2, 3, 4],
920 DmapType::as_bytes(&u32::from_bytes(&[1, 2, 3, 4])?)
921 );
922 assert_eq!(
923 vec![1, 0, 0, 0],
924 DmapType::as_bytes(&f32::from_bytes(&[1, 0, 0, 0])?)
925 );
926 assert_eq!(
927 vec![1, 2, 3, 4, 5, 6, 7, 8],
928 DmapType::as_bytes(&u64::from_bytes(&[1, 2, 3, 4, 5, 6, 7, 8])?)
929 );
930 assert_eq!(
931 vec![1, 0, 0, 0, 1, 2, 3, 4],
932 DmapType::as_bytes(&i64::from_bytes(&[1, 0, 0, 0, 1, 2, 3, 4])?)
933 );
934 assert_eq!(
935 vec![1, 2, 3, 4, 4, 32, 2, 1],
936 DmapType::as_bytes(&f64::from_bytes(&[1, 2, 3, 4, 4, 32, 2, 1])?)
937 );
938 Ok(())
939 }
940
941 #[test]
942 fn types() -> Result<()> {
943 assert_eq!(Type::from_key(1)?, Type::Char);
944 assert_eq!(Type::from_key(2)?, Type::Short);
945 assert_eq!(Type::from_key(3)?, Type::Int);
946 assert_eq!(Type::from_key(10)?, Type::Long);
947 assert_eq!(Type::from_key(16)?, Type::Uchar);
948 assert_eq!(Type::from_key(17)?, Type::Ushort);
949 assert_eq!(Type::from_key(18)?, Type::Uint);
950 assert_eq!(Type::from_key(19)?, Type::Ulong);
951 assert_eq!(Type::from_key(4)?, Type::Float);
952 assert_eq!(Type::from_key(8)?, Type::Double);
953 assert_eq!(Type::from_key(9)?, Type::String);
954 assert!(Type::from_key(-1).is_err());
955 assert!(Type::from_key(15).is_err());
956 assert!(Type::from_key(0).is_err());
957
958 assert_eq!(Type::Char.key(), 1);
959 assert_eq!(Type::Short.key(), 2);
960 assert_eq!(Type::Int.key(), 3);
961 assert_eq!(Type::Long.key(), 10);
962 assert_eq!(Type::Uchar.key(), 16);
963 assert_eq!(Type::Ushort.key(), 17);
964 assert_eq!(Type::Uint.key(), 18);
965 assert_eq!(Type::Ulong.key(), 19);
966 assert_eq!(Type::Float.key(), 4);
967 assert_eq!(Type::Double.key(), 8);
968 assert_eq!(Type::String.key(), 9);
969
970 assert_eq!(Type::Char.size(), 1);
971 assert_eq!(Type::Short.size(), 2);
972 assert_eq!(Type::Int.size(), 4);
973 assert_eq!(Type::Long.size(), 8);
974 assert_eq!(Type::Uchar.size(), 1);
975 assert_eq!(Type::Ushort.size(), 2);
976 assert_eq!(Type::Uint.size(), 4);
977 assert_eq!(Type::Ulong.size(), 8);
978 assert_eq!(Type::Float.size(), 4);
979 assert_eq!(Type::Double.size(), 8);
980 assert_eq!(Type::String.size(), 0);
981
982 Ok(())
983 }
984
985 #[test]
986 fn dmapscalar() -> Result<()> {
987 assert_eq!(DmapScalar::Char(0).get_type(), Type::Char);
988 assert_eq!(DmapScalar::Short(0).get_type(), Type::Short);
989 assert_eq!(DmapScalar::Int(0).get_type(), Type::Int);
990 assert_eq!(DmapScalar::Long(0).get_type(), Type::Long);
991 assert_eq!(DmapScalar::Uchar(0).get_type(), Type::Uchar);
992 assert_eq!(DmapScalar::Ushort(0).get_type(), Type::Ushort);
993 assert_eq!(DmapScalar::Uint(0).get_type(), Type::Uint);
994 assert_eq!(DmapScalar::Ulong(0).get_type(), Type::Ulong);
995 assert_eq!(DmapScalar::Float(0.0).get_type(), Type::Float);
996 assert_eq!(DmapScalar::Double(0.0).get_type(), Type::Double);
997 assert_eq!(
998 DmapScalar::String("test".to_string()).get_type(),
999 Type::String
1000 );
1001
1002 let x = DmapScalar::Char(-1);
1003 assert_eq!(x.cast_as(&Type::Short)?, DmapScalar::Short(-1));
1004 assert!(x.cast_as(&Type::Float).is_ok());
1005 assert!(x.cast_as(&Type::Uchar).is_err());
1006 assert!(x.cast_as(&Type::String).is_err());
1007
1008 let x = DmapScalar::Uchar(255);
1009 assert_eq!(x.cast_as(&Type::Short)?, DmapScalar::Short(255));
1010 assert!(x.cast_as(&Type::Char).is_err());
1011 assert!(x.cast_as(&Type::Float).is_ok());
1012 assert!(x.cast_as(&Type::Uchar).is_ok());
1013 assert!(x.cast_as(&Type::String).is_err());
1014
1015 let x = DmapScalar::Short(256);
1016 assert_eq!(x.cast_as(&Type::Short)?, DmapScalar::Short(256));
1017 assert!(x.cast_as(&Type::Char).is_err());
1018 assert_eq!(x.cast_as(&Type::Ushort)?, DmapScalar::Ushort(256));
1019 assert!(x.cast_as(&Type::Uchar).is_err());
1020 assert!(x.cast_as(&Type::Float).is_ok());
1021 assert!(x.cast_as(&Type::String).is_err());
1022
1023 let x = DmapScalar::Float(1.0);
1024 assert!(x.cast_as(&Type::Double).is_ok());
1025 assert!(x.cast_as(&Type::Char).is_err());
1026 assert!(x.cast_as(&Type::Uchar).is_err());
1027 assert!(x.cast_as(&Type::Float).is_ok());
1028 assert!(x.cast_as(&Type::String).is_err());
1029
1030 let x = DmapScalar::String("test".to_string());
1031 assert!(x.cast_as(&Type::Char).is_err());
1032 assert!(x.cast_as(&Type::Short).is_err());
1033 assert!(x.cast_as(&Type::Int).is_err());
1034 assert!(x.cast_as(&Type::Long).is_err());
1035 assert!(x.cast_as(&Type::Uchar).is_err());
1036 assert!(x.cast_as(&Type::Ushort).is_err());
1037 assert!(x.cast_as(&Type::Uint).is_err());
1038 assert!(x.cast_as(&Type::Ulong).is_err());
1039 assert!(x.cast_as(&Type::Float).is_err());
1040 assert!(x.cast_as(&Type::Double).is_err());
1041
1042 assert_eq!(
1043 DmapScalar::Char(8).as_bytes(),
1044 vec![Type::Char.key() as u8, 8]
1045 );
1046 assert_eq!(
1047 DmapScalar::Short(256).as_bytes(),
1048 vec![Type::Short.key() as u8, 0, 1]
1049 );
1050 assert_eq!(
1051 DmapScalar::Int(256).as_bytes(),
1052 vec![Type::Int.key() as u8, 0, 1, 0, 0]
1053 );
1054 assert_eq!(
1055 DmapScalar::Long(512).as_bytes(),
1056 vec![Type::Long.key() as u8, 0, 2, 0, 0, 0, 0, 0, 0]
1057 );
1058 assert_eq!(
1059 DmapScalar::Uchar(8).as_bytes(),
1060 vec![Type::Uchar.key() as u8, 8]
1061 );
1062 assert_eq!(
1063 DmapScalar::Ushort(256).as_bytes(),
1064 vec![Type::Ushort.key() as u8, 0, 1]
1065 );
1066 assert_eq!(
1067 DmapScalar::Uint(256).as_bytes(),
1068 vec![Type::Uint.key() as u8, 0, 1, 0, 0]
1069 );
1070 assert_eq!(
1071 DmapScalar::Ulong(512).as_bytes(),
1072 vec![Type::Ulong.key() as u8, 0, 2, 0, 0, 0, 0, 0, 0]
1073 );
1074 assert_eq!(
1075 DmapScalar::Float(0.0).as_bytes(),
1076 vec![Type::Float.key() as u8, 0, 0, 0, 0]
1077 );
1078 assert_eq!(
1079 DmapScalar::Double(0.0).as_bytes(),
1080 vec![Type::Double.key() as u8, 0, 0, 0, 0, 0, 0, 0, 0]
1081 );
1082 assert_eq!(
1083 DmapScalar::String("test".to_string()).as_bytes(),
1084 vec![Type::String.key() as u8, 116, 101, 115, 116, 0]
1085 );
1086
1087 Ok(())
1088 }
1089
1090 #[test]
1091 fn dmapvec() -> Result<()> {
1092 let arr = DmapVec::Char(array![0, 1, 2, 3, 4].into_dyn());
1093 assert_eq!(arr.get_type(), Type::Char);
1094 let arr = DmapVec::Uchar(array![0, 1, 2, 3, 4].into_dyn());
1095 assert_eq!(arr.get_type(), Type::Uchar);
1096 let arr = DmapVec::Short(array![0, 1, 2, 3, 4].into_dyn());
1097 assert_eq!(arr.get_type(), Type::Short);
1098 let arr = DmapVec::Ushort(array![0, 1, 2, 3, 4].into_dyn());
1099 assert_eq!(arr.get_type(), Type::Ushort);
1100 let arr = DmapVec::Int(array![0, 1, 2, 3, 4].into_dyn());
1101 assert_eq!(arr.get_type(), Type::Int);
1102 let arr = DmapVec::Uint(array![[0, 1, 2], [3, 4, 5]].into_dyn());
1103 assert_eq!(arr.get_type(), Type::Uint);
1104 let arr = DmapVec::Long(array![0, 1, 2, 3, 4].into_dyn());
1105 assert_eq!(arr.get_type(), Type::Long);
1106 let arr = DmapVec::Ulong(array![0, 1, 2, 3, 4].into_dyn());
1107 assert_eq!(arr.get_type(), Type::Ulong);
1108 let arr = DmapVec::Float(array![0.0, 1.0, 2.0, 3.0, 4.0].into_dyn());
1109 assert_eq!(arr.get_type(), Type::Float);
1110 let arr = DmapVec::Double(array![0.0, 1.0, 2.0, 3.0, 4.0].into_dyn());
1111 assert_eq!(arr.get_type(), Type::Double);
1112
1113 Ok(())
1114 }
1115
1116 #[test]
1117 fn check_fields_in_indexmap() -> Result<()> {
1118 use ndarray::array;
1119
1120 let mut rec = IndexMap::<String, DmapField>::new();
1121 let res = check_scalar(&rec, "test", &Type::Char);
1122 assert!(res.is_err());
1123 let res = check_scalar_opt(&rec, "test", &Type::Char);
1124 assert!(res.is_ok());
1125 let res = check_vector(&rec, "test", &Type::Char);
1126 assert!(res.is_err());
1127 let res = check_vector_opt(&rec, "test", &Type::Char);
1128 assert!(res.is_ok());
1129
1130 let res = rec.insert("test".to_string(), DmapField::from(1i32));
1131 assert!(res.is_none());
1132 let res = check_scalar(&rec, "test", &Type::Int);
1133 assert!(res.is_ok());
1134 let res = check_scalar_opt(&rec, "test", &Type::Char);
1135 assert!(res.is_err());
1136 let res = check_scalar_opt(&rec, "test", &Type::Int);
1137 assert!(res.is_ok());
1138 let res = check_vector(&rec, "test", &Type::Char);
1139 assert!(res.is_err());
1140 let res = check_vector_opt(&rec, "test", &Type::Char);
1141 assert!(res.is_err());
1142
1143 let test_vec = array![1.0f32, 2.0f32].into_dyn();
1144 let res = rec.insert("test_vec".to_string(), test_vec.into());
1145 assert!(res.is_none());
1146 let res = check_scalar(&rec, "test_vec", &Type::Float);
1147 assert!(res.is_err());
1148 let res = check_scalar_opt(&rec, "test_vec", &Type::Float);
1149 assert!(res.is_err());
1150 let res = check_vector(&rec, "test_vec", &Type::Float);
1151 assert!(res.is_ok());
1152 let res = check_vector(&rec, "test_vec", &Type::Double);
1153 assert!(res.is_err());
1154 let res = check_vector_opt(&rec, "test_vec", &Type::Float);
1155 assert!(res.is_ok());
1156 let res = check_vector_opt(&rec, "test_vec", &Type::Int);
1157 assert!(res.is_err());
1158
1159 Ok(())
1160 }
1161}