1use crate::error::DmapError;
3use indexmap::IndexMap;
4use numpy::array::PyArray;
5use numpy::ndarray::ArrayD;
6use numpy::PyArrayMethods;
7use paste::paste;
8use pyo3::exceptions::PyValueError;
9use pyo3::prelude::*;
10use pyo3::{Bound, FromPyObject, PyAny, PyResult, Python};
11use std::cmp::PartialEq;
12use std::fmt::{Display, Formatter};
13use std::io::Cursor;
14use zerocopy::{AsBytes, ByteOrder, FromBytes, LittleEndian};
15
16type Result<T> = std::result::Result<T, DmapError>;
17
18pub struct Fields<'a> {
20 pub all_fields: Vec<&'a str>,
22 pub scalars_required: Vec<(&'a str, Type)>,
24 pub scalars_optional: Vec<(&'a str, Type)>,
26 pub vectors_required: Vec<(&'a str, Type)>,
28 pub vectors_optional: Vec<(&'a str, Type)>,
30 pub vector_dim_groups: Vec<Vec<&'a str>>,
32 pub data_fields: Vec<&'a str>,
34}
35
36#[derive(Debug, PartialEq, Clone)]
40pub enum Type {
41 Char,
42 Short,
43 Int,
44 Long,
45 Uchar,
46 Ushort,
47 Uint,
48 Ulong,
49 Float,
50 Double,
51 String,
52}
53impl Display for Type {
54 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
55 match self {
56 Self::Char => write!(f, "CHAR"),
57 Self::Short => write!(f, "SHORT"),
58 Self::Int => write!(f, "INT"),
59 Self::Float => write!(f, "FLOAT"),
60 Self::Double => write!(f, "DOUBLE"),
61 Self::String => write!(f, "STRING"),
62 Self::Long => write!(f, "LONG"),
63 Self::Uchar => write!(f, "UCHAR"),
64 Self::Ushort => write!(f, "USHORT"),
65 Self::Uint => write!(f, "UINT"),
66 Self::Ulong => write!(f, "ULONG"),
67 }
68 }
69}
70impl Type {
71 fn from_key(key: i8) -> Result<Self> {
74 let data = match key {
75 1 => Self::Char,
76 2 => Self::Short,
77 3 => Self::Int,
78 10 => Self::Long,
79 16 => Self::Uchar,
80 17 => Self::Ushort,
81 18 => Self::Uint,
82 19 => Self::Ulong,
83 4 => Self::Float,
84 8 => Self::Double,
85 9 => Self::String,
86 x => Err(DmapError::InvalidKey(x))?,
87 };
88 Ok(data)
89 }
90 fn key(&self) -> i8 {
92 match self {
93 Self::Char => 1,
94 Self::Short => 2,
95 Self::Int => 3,
96 Self::Long => 10,
97 Self::Uchar => 16,
98 Self::Ushort => 17,
99 Self::Uint => 18,
100 Self::Ulong => 19,
101 Self::Float => 4,
102 Self::Double => 8,
103 Self::String => 9,
104 }
105 }
106 pub fn size(&self) -> usize {
108 match self {
109 Self::Char => 1,
110 Self::Short => 2,
111 Self::Int => 4,
112 Self::Long => 8,
113 Self::Uchar => 1,
114 Self::Ushort => 2,
115 Self::Uint => 4,
116 Self::Ulong => 8,
117 Self::Float => 4,
118 Self::Double => 8,
119 Self::String => 0,
120 }
121 }
122}
123
124#[derive(Debug, Clone, PartialEq, FromPyObject, IntoPyObject)]
126#[repr(C)]
127pub enum DmapScalar {
128 Char(i8),
129 Short(i16),
130 Int(i32),
131 Long(i64),
132 Uchar(u8),
133 Ushort(u16),
134 Uint(u32),
135 Ulong(u64),
136 Float(f32),
137 Double(f64),
138 String(String),
139}
140impl DmapScalar {
141 pub(crate) fn get_type(&self) -> Type {
143 match self {
144 Self::Char(_) => Type::Char,
145 Self::Short(_) => Type::Short,
146 Self::Int(_) => Type::Int,
147 Self::Long(_) => Type::Long,
148 Self::Uchar(_) => Type::Uchar,
149 Self::Ushort(_) => Type::Ushort,
150 Self::Uint(_) => Type::Uint,
151 Self::Ulong(_) => Type::Ulong,
152 Self::Float(_) => Type::Float,
153 Self::Double(_) => Type::Double,
154 Self::String(_) => Type::String,
155 }
156 }
157
158 pub(crate) fn cast_as(&self, new_type: &Type) -> Result<Self> {
160 match new_type {
161 Type::Char => Ok(Self::Char(i8::try_from(self.clone())?)),
162 Type::Short => Ok(Self::Short(i16::try_from(self.clone())?)),
163 Type::Int => Ok(Self::Int(i32::try_from(self.clone())?)),
164 Type::Long => Ok(Self::Long(i64::try_from(self.clone())?)),
165 Type::Uchar => Ok(Self::Uchar(u8::try_from(self.clone())?)),
166 Type::Ushort => Ok(Self::Ushort(u16::try_from(self.clone())?)),
167 Type::Uint => Ok(Self::Uint(u32::try_from(self.clone())?)),
168 Type::Ulong => Ok(Self::Ulong(u64::try_from(self.clone())?)),
169 Type::Float => Ok(Self::Float(f32::try_from(self.clone())?)),
170 Type::Double => Ok(Self::Double(f64::try_from(self.clone())?)),
171 Type::String => Err(DmapError::InvalidScalar(
172 "Unable to cast value to String".to_string(),
173 )),
174 }
175 }
176 pub(crate) fn as_bytes(&self) -> Vec<u8> {
178 let mut bytes: Vec<u8> = DmapType::as_bytes(&self.get_type().key()).to_vec();
179 let mut data_bytes: Vec<u8> = match self {
180 Self::Char(x) => DmapType::as_bytes(x),
181 Self::Short(x) => DmapType::as_bytes(x),
182 Self::Int(x) => DmapType::as_bytes(x),
183 Self::Long(x) => DmapType::as_bytes(x),
184 Self::Uchar(x) => DmapType::as_bytes(x),
185 Self::Ushort(x) => DmapType::as_bytes(x),
186 Self::Uint(x) => DmapType::as_bytes(x),
187 Self::Ulong(x) => DmapType::as_bytes(x),
188 Self::Float(x) => DmapType::as_bytes(x),
189 Self::Double(x) => DmapType::as_bytes(x),
190 Self::String(x) => DmapType::as_bytes(x),
191 };
192 bytes.append(&mut data_bytes);
193 bytes
194 }
195}
196impl Display for DmapScalar {
197 fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
198 match self {
199 Self::Char(x) => write!(f, "CHAR {x}"),
200 Self::Short(x) => write!(f, "SHORT {x}"),
201 Self::Int(x) => write!(f, "INT {x}"),
202 Self::Float(x) => write!(f, "FLOAT {x}"),
203 Self::Double(x) => write!(f, "DOUBLE {x}"),
204 Self::String(x) => write!(f, "STRING {x}"),
205 Self::Long(x) => write!(f, "LONG {x}"),
206 Self::Uchar(x) => write!(f, "UCHAR {x}"),
207 Self::Ushort(x) => write!(f, "USHORT {x}"),
208 Self::Uint(x) => write!(f, "UINT {x}"),
209 Self::Ulong(x) => write!(f, "ULONG {x}"),
210 }
211 }
212}
213macro_rules! vec_to_bytes {
232 ($bytes:ident, $x:ident) => {{
233 $bytes.extend(($x.ndim() as i32).to_le_bytes());
234 for &dim in $x.shape().iter().rev() {
235 $bytes.extend((dim as i32).to_le_bytes());
236 }
237 for y in $x.iter() {
238 $bytes.append(&mut DmapType::as_bytes(y).to_vec());
239 }
240 }};
241}
242
243#[derive(Clone, Debug, PartialEq)]
245pub enum DmapVec {
246 Char(ArrayD<i8>),
247 Short(ArrayD<i16>),
248 Int(ArrayD<i32>),
249 Long(ArrayD<i64>),
250 Uchar(ArrayD<u8>),
251 Ushort(ArrayD<u16>),
252 Uint(ArrayD<u32>),
253 Ulong(ArrayD<u64>),
254 Float(ArrayD<f32>),
255 Double(ArrayD<f64>),
256}
257impl DmapVec {
258 #[inline]
260 pub(crate) fn get_type(&self) -> Type {
261 match self {
262 DmapVec::Char(_) => Type::Char,
263 DmapVec::Short(_) => Type::Short,
264 DmapVec::Int(_) => Type::Int,
265 DmapVec::Long(_) => Type::Long,
266 DmapVec::Uchar(_) => Type::Uchar,
267 DmapVec::Ushort(_) => Type::Ushort,
268 DmapVec::Uint(_) => Type::Uint,
269 DmapVec::Ulong(_) => Type::Ulong,
270 DmapVec::Float(_) => Type::Float,
271 DmapVec::Double(_) => Type::Double,
272 }
273 }
274 #[inline]
276 pub(crate) fn as_bytes(&self) -> Vec<u8> {
277 let mut bytes: Vec<u8> = DmapType::as_bytes(&self.get_type().key()).to_vec();
278 match self {
279 DmapVec::Char(x) => vec_to_bytes!(bytes, x),
280 DmapVec::Short(x) => vec_to_bytes!(bytes, x),
281 DmapVec::Int(x) => vec_to_bytes!(bytes, x),
282 DmapVec::Long(x) => vec_to_bytes!(bytes, x),
283 DmapVec::Uchar(x) => vec_to_bytes!(bytes, x),
284 DmapVec::Ushort(x) => vec_to_bytes!(bytes, x),
285 DmapVec::Uint(x) => vec_to_bytes!(bytes, x),
286 DmapVec::Ulong(x) => vec_to_bytes!(bytes, x),
287 DmapVec::Float(x) => vec_to_bytes!(bytes, x),
288 DmapVec::Double(x) => vec_to_bytes!(bytes, x),
289 };
290 bytes
291 }
292
293 #[must_use]
306 pub fn shape(&self) -> &[usize] {
307 match self {
308 DmapVec::Char(x) => x.shape(),
309 DmapVec::Short(x) => x.shape(),
310 DmapVec::Int(x) => x.shape(),
311 DmapVec::Long(x) => x.shape(),
312 DmapVec::Uchar(x) => x.shape(),
313 DmapVec::Ushort(x) => x.shape(),
314 DmapVec::Uint(x) => x.shape(),
315 DmapVec::Ulong(x) => x.shape(),
316 DmapVec::Float(x) => x.shape(),
317 DmapVec::Double(x) => x.shape(),
318 }
319 }
320}
321impl<'py> IntoPyObject<'py> for DmapVec {
322 type Target = PyAny;
323 type Output = Bound<'py, Self::Target>;
324 type Error = std::convert::Infallible;
325
326 fn into_pyobject(self, py: Python<'py>) -> std::result::Result<Self::Output, Self::Error> {
327 Ok(match self {
328 DmapVec::Char(x) => PyArray::from_owned_array(py, x).into_any(),
329 DmapVec::Short(x) => PyArray::from_owned_array(py, x).into_any(),
330 DmapVec::Int(x) => PyArray::from_owned_array(py, x).into_any(),
331 DmapVec::Long(x) => PyArray::from_owned_array(py, x).into_any(),
332 DmapVec::Uchar(x) => PyArray::from_owned_array(py, x).into_any(),
333 DmapVec::Ushort(x) => PyArray::from_owned_array(py, x).into_any(),
334 DmapVec::Uint(x) => PyArray::from_owned_array(py, x).into_any(),
335 DmapVec::Ulong(x) => PyArray::from_owned_array(py, x).into_any(),
336 DmapVec::Float(x) => PyArray::from_owned_array(py, x).into_any(),
337 DmapVec::Double(x) => PyArray::from_owned_array(py, x).into_any(),
338 })
339 }
340}
341impl<'py> FromPyObject<'py> for DmapVec {
342 fn extract_bound(ob: &Bound<'py, PyAny>) -> PyResult<Self> {
343 if let Ok(x) = ob.downcast::<PyArray<u8, _>>() {
344 Ok(DmapVec::Uchar(x.to_owned_array()))
345 } else if let Ok(x) = ob.downcast::<PyArray<u16, _>>() {
346 Ok(DmapVec::Ushort(x.to_owned_array()))
347 } else if let Ok(x) = ob.downcast::<PyArray<u32, _>>() {
348 Ok(DmapVec::Uint(x.to_owned_array()))
349 } else if let Ok(x) = ob.downcast::<PyArray<u64, _>>() {
350 Ok(DmapVec::Ulong(x.to_owned_array()))
351 } else if let Ok(x) = ob.downcast::<PyArray<i8, _>>() {
352 Ok(DmapVec::Char(x.to_owned_array()))
353 } else if let Ok(x) = ob.downcast::<PyArray<i16, _>>() {
354 Ok(DmapVec::Short(x.to_owned_array()))
355 } else if let Ok(x) = ob.downcast::<PyArray<i32, _>>() {
356 Ok(DmapVec::Int(x.to_owned_array()))
357 } else if let Ok(x) = ob.downcast::<PyArray<i64, _>>() {
358 Ok(DmapVec::Long(x.to_owned_array()))
359 } else if let Ok(x) = ob.downcast::<PyArray<f32, _>>() {
360 Ok(DmapVec::Float(x.to_owned_array()))
361 } else if let Ok(x) = ob.downcast::<PyArray<f64, _>>() {
362 Ok(DmapVec::Double(x.to_owned_array()))
363 } else {
364 Err(PyValueError::new_err("Could not extract vector"))
365 }
366 }
367}
368
369macro_rules! vec_impls {
375 ($type:ty, $enum_var:path) => {
376 impl From<$type> for DmapVec {
377 #[inline]
378 fn from(value: $type) -> Self {
379 $enum_var(value)
380 }
381 }
382
383 impl TryFrom<DmapVec> for $type {
384 type Error = DmapError;
385
386 fn try_from(value: DmapVec) -> std::result::Result<Self, Self::Error> {
387 if let $enum_var(x) = value {
388 Ok(x)
389 } else {
390 Err(DmapError::InvalidVector(format!(
391 "Cannot convert to {}",
392 stringify!($type)
393 )))
394 }
395 }
396 }
397
398 impl From<$type> for DmapField {
399 #[inline]
400 fn from(value: $type) -> Self {
401 DmapField::Vector($enum_var(value))
402 }
403 }
404
405 impl TryFrom<DmapField> for $type {
406 type Error = DmapError;
407
408 fn try_from(value: DmapField) -> std::result::Result<Self, Self::Error> {
409 match value {
410 DmapField::Vector(x) => x.try_into(),
411 _ => Err(Self::Error::InvalidVector(format!(
412 "Cannot interpret as {}",
413 stringify!($type)
414 ))),
415 }
416 }
417 }
418 };
419}
420
421vec_impls!(ArrayD<i8>, DmapVec::Char);
422vec_impls!(ArrayD<i16>, DmapVec::Short);
423vec_impls!(ArrayD<i32>, DmapVec::Int);
424vec_impls!(ArrayD<i64>, DmapVec::Long);
425vec_impls!(ArrayD<u8>, DmapVec::Uchar);
426vec_impls!(ArrayD<u16>, DmapVec::Ushort);
427vec_impls!(ArrayD<u32>, DmapVec::Uint);
428vec_impls!(ArrayD<u64>, DmapVec::Ulong);
429vec_impls!(ArrayD<f32>, DmapVec::Float);
430vec_impls!(ArrayD<f64>, DmapVec::Double);
431
432#[derive(Debug, Clone, PartialEq, FromPyObject, IntoPyObject)]
437#[repr(C)]
438pub enum DmapField {
439 Vector(DmapVec),
440 Scalar(DmapScalar),
441}
442impl DmapField {
443 #[inline]
445 #[must_use]
446 pub fn as_bytes(&self) -> Vec<u8> {
447 match self {
448 Self::Scalar(x) => x.as_bytes(),
449 Self::Vector(x) => x.as_bytes(),
450 }
451 }
452}
453macro_rules! scalar_impls {
469 ($type:ty, $enum_var:path, $type_var:path) => {
470 impl From<$type> for DmapField {
471 fn from(value: $type) -> Self {
472 DmapField::Scalar($enum_var(value))
473 }
474 }
475 impl TryFrom<DmapField> for $type {
476 type Error = DmapError;
477
478 fn try_from(value: DmapField) -> std::result::Result<Self, Self::Error> {
479 match value {
480 DmapField::Scalar(x) => x.try_into(),
481 _ => Err(Self::Error::InvalidScalar(format!(
482 "Cannot interpret {value:?} as {}",
483 stringify!($type)
484 ))),
485 }
486 }
487 }
488 };
489}
490
491scalar_impls!(i8, DmapScalar::Char, Type::Char);
492scalar_impls!(i16, DmapScalar::Short, Type::Short);
493scalar_impls!(i32, DmapScalar::Int, Type::Int);
494scalar_impls!(i64, DmapScalar::Long, Type::Long);
495scalar_impls!(u8, DmapScalar::Uchar, Type::Uchar);
496scalar_impls!(u16, DmapScalar::Ushort, Type::Ushort);
497scalar_impls!(u32, DmapScalar::Uint, Type::Uint);
498scalar_impls!(u64, DmapScalar::Ulong, Type::Ulong);
499scalar_impls!(f32, DmapScalar::Float, Type::Float);
500scalar_impls!(f64, DmapScalar::Double, Type::Double);
501scalar_impls!(String, DmapScalar::String, Type::String);
502
503pub trait DmapType: std::fmt::Debug {
505 fn size() -> usize
507 where
508 Self: Sized;
509 fn as_bytes(&self) -> Vec<u8>;
511 fn from_bytes(bytes: &[u8]) -> Result<Self>
516 where
517 Self: Sized;
518 fn dmap_type() -> Type;
520}
521
522macro_rules! type_impls {
525 ($type:ty, $enum_var:path, 1) => {
527 impl DmapType for $type {
528 #[inline]
529 fn size() -> usize { 1 }
530
531 #[inline]
532 fn as_bytes(&self) -> Vec<u8> {
533 AsBytes::as_bytes(self).to_vec()
534 }
535
536 #[inline]
537 fn from_bytes(bytes: &[u8]) -> Result<Self>
538 where
539 Self: Sized,
540 {
541 Self::read_from(bytes).ok_or(DmapError::CorruptStream("Unable to interpret bytes"))
542 }
543
544 #[inline]
545 fn dmap_type() -> Type { $enum_var }
546 }
547 };
548 ($type:ty, $enum_var:path, $num_bytes:expr) => {
550 paste! {
551 impl DmapType for $type {
552 #[inline]
553 fn size() -> usize { $num_bytes }
554
555 #[inline]
556 fn as_bytes(&self) -> Vec<u8> {
557 let mut bytes = [0; $num_bytes];
558 LittleEndian::[< write_ $type >](&mut bytes, *self);
559 bytes.to_vec()
560 }
561
562 #[inline]
563 fn from_bytes(bytes: &[u8]) -> Result<Self>
564 where
565 Self: Sized,
566 {
567 Self::read_from(bytes).ok_or(DmapError::CorruptStream("Unable to interpret bytes"))
568 }
569
570 #[inline]
571 fn dmap_type() -> Type { $enum_var }
572 }
573 }
574 }
575}
576
577type_impls!(i8, Type::Char, 1);
578type_impls!(i16, Type::Short, 2);
579type_impls!(i32, Type::Int, 4);
580type_impls!(i64, Type::Long, 8);
581type_impls!(u8, Type::Uchar, 1);
582type_impls!(u16, Type::Ushort, 2);
583type_impls!(u32, Type::Uint, 4);
584type_impls!(u64, Type::Ulong, 8);
585type_impls!(f32, Type::Float, 4);
586type_impls!(f64, Type::Double, 8);
587
588impl DmapType for String {
590 #[inline]
591 fn size() -> usize {
592 0
593 }
594
595 #[inline]
596 fn as_bytes(&self) -> Vec<u8> {
597 let mut bytes = self.as_bytes().to_vec();
598 bytes.push(0); bytes
600 }
601
602 #[inline]
603 fn from_bytes(bytes: &[u8]) -> Result<Self> {
604 let data = String::from_utf8(bytes.to_owned())
605 .map_err(|_| DmapError::InvalidScalar("Cannot convert bytes to String".to_string()))?;
606 Ok(data.trim_end_matches(char::from(0)).to_string())
607 }
608
609 #[inline]
610 fn dmap_type() -> Type {
611 Type::String
612 }
613}
614
615impl TryFrom<DmapScalar> for u8 {
616 type Error = DmapError;
617 fn try_from(value: DmapScalar) -> std::result::Result<Self, Self::Error> {
618 match value {
619 DmapScalar::Char(x) => Ok(u8::try_from(x)?),
620 DmapScalar::Short(x) => Ok(u8::try_from(x)?),
621 DmapScalar::Int(x) => Ok(u8::try_from(x)?),
622 DmapScalar::Long(x) => Ok(u8::try_from(x)?),
623 DmapScalar::Uchar(x) => Ok(x),
624 DmapScalar::Ushort(x) => Ok(u8::try_from(x)?),
625 DmapScalar::Uint(x) => Ok(u8::try_from(x)?),
626 DmapScalar::Ulong(x) => Ok(u8::try_from(x)?),
627 DmapScalar::Float(x) => Err(DmapError::InvalidScalar(format!(
628 "Unable to convert {x}_f32 to u8"
629 ))),
630 DmapScalar::Double(x) => Err(DmapError::InvalidScalar(format!(
631 "Unable to convert {x}_f64 to u8"
632 ))),
633 DmapScalar::String(x) => Err(DmapError::InvalidScalar(format!(
634 "Unable to convert {x} to u8"
635 ))),
636 }
637 }
638}
639impl TryFrom<DmapScalar> for u16 {
640 type Error = DmapError;
641 fn try_from(value: DmapScalar) -> std::result::Result<Self, Self::Error> {
642 match value {
643 DmapScalar::Char(x) => Ok(u16::try_from(x)?),
644 DmapScalar::Short(x) => Ok(u16::try_from(x)?),
645 DmapScalar::Int(x) => Ok(u16::try_from(x)?),
646 DmapScalar::Long(x) => Ok(u16::try_from(x)?),
647 DmapScalar::Uchar(x) => Ok(x as u16),
648 DmapScalar::Ushort(x) => Ok(x),
649 DmapScalar::Uint(x) => Ok(u16::try_from(x)?),
650 DmapScalar::Ulong(x) => Ok(u16::try_from(x)?),
651 DmapScalar::Float(x) => Err(DmapError::InvalidScalar(format!(
652 "Unable to convert {x}_f32 to u16"
653 ))),
654 DmapScalar::Double(x) => Err(DmapError::InvalidScalar(format!(
655 "Unable to convert {x}_f64 to u16"
656 ))),
657 DmapScalar::String(x) => Err(DmapError::InvalidScalar(format!(
658 "Unable to convert {x} to u16"
659 ))),
660 }
661 }
662}
663impl TryFrom<DmapScalar> for u32 {
664 type Error = DmapError;
665 fn try_from(value: DmapScalar) -> std::result::Result<Self, Self::Error> {
666 match value {
667 DmapScalar::Char(x) => Ok(u32::try_from(x)?),
668 DmapScalar::Short(x) => Ok(u32::try_from(x)?),
669 DmapScalar::Int(x) => Ok(u32::try_from(x)?),
670 DmapScalar::Long(x) => Ok(u32::try_from(x)?),
671 DmapScalar::Uchar(x) => Ok(x as u32),
672 DmapScalar::Ushort(x) => Ok(x as u32),
673 DmapScalar::Uint(x) => Ok(x),
674 DmapScalar::Ulong(x) => Ok(u32::try_from(x)?),
675 DmapScalar::Float(x) => Err(DmapError::InvalidScalar(format!(
676 "Unable to convert {x}_f32 to u32"
677 ))),
678 DmapScalar::Double(x) => Err(DmapError::InvalidScalar(format!(
679 "Unable to convert {x}_f64 to u32"
680 ))),
681 DmapScalar::String(x) => Err(DmapError::InvalidScalar(format!(
682 "Unable to convert {x} to u32"
683 ))),
684 }
685 }
686}
687impl TryFrom<DmapScalar> for u64 {
688 type Error = DmapError;
689 fn try_from(value: DmapScalar) -> std::result::Result<Self, Self::Error> {
690 match value {
691 DmapScalar::Char(x) => Ok(u64::try_from(x)?),
692 DmapScalar::Short(x) => Ok(u64::try_from(x)?),
693 DmapScalar::Int(x) => Ok(u64::try_from(x)?),
694 DmapScalar::Long(x) => Ok(u64::try_from(x)?),
695 DmapScalar::Uchar(x) => Ok(x as u64),
696 DmapScalar::Ushort(x) => Ok(x as u64),
697 DmapScalar::Uint(x) => Ok(x as u64),
698 DmapScalar::Ulong(x) => Ok(x),
699 DmapScalar::Float(x) => Err(DmapError::InvalidScalar(format!(
700 "Unable to convert {x}_f32 to u64"
701 ))),
702 DmapScalar::Double(x) => Err(DmapError::InvalidScalar(format!(
703 "Unable to convert {x}_f64 to u64"
704 ))),
705 DmapScalar::String(x) => Err(DmapError::InvalidScalar(format!(
706 "Unable to convert {x} to u64"
707 ))),
708 }
709 }
710}
711impl TryFrom<DmapScalar> for i8 {
712 type Error = DmapError;
713 fn try_from(value: DmapScalar) -> std::result::Result<Self, Self::Error> {
714 match value {
715 DmapScalar::Char(x) => Ok(x),
716 DmapScalar::Short(x) => Ok(i8::try_from(x)?),
717 DmapScalar::Int(x) => Ok(i8::try_from(x)?),
718 DmapScalar::Long(x) => Ok(i8::try_from(x)?),
719 DmapScalar::Uchar(x) => Ok(i8::try_from(x)?),
720 DmapScalar::Ushort(x) => Ok(i8::try_from(x)?),
721 DmapScalar::Uint(x) => Ok(i8::try_from(x)?),
722 DmapScalar::Ulong(x) => Ok(i8::try_from(x)?),
723 DmapScalar::Float(x) => Err(DmapError::InvalidScalar(format!(
724 "Unable to convert {x}_f32 to i8"
725 ))),
726 DmapScalar::Double(x) => Err(DmapError::InvalidScalar(format!(
727 "Unable to convert {x}_f64 to i8"
728 ))),
729 DmapScalar::String(x) => Err(DmapError::InvalidScalar(format!(
730 "Unable to convert {x} to i8"
731 ))),
732 }
733 }
734}
735impl TryFrom<DmapScalar> for i16 {
736 type Error = DmapError;
737 fn try_from(value: DmapScalar) -> std::result::Result<Self, Self::Error> {
738 match value {
739 DmapScalar::Char(x) => Ok(x as i16),
740 DmapScalar::Short(x) => Ok(x),
741 DmapScalar::Int(x) => Ok(i16::try_from(x)?),
742 DmapScalar::Long(x) => Ok(i16::try_from(x)?),
743 DmapScalar::Uchar(x) => Ok(x as i16),
744 DmapScalar::Ushort(x) => Ok(i16::try_from(x)?),
745 DmapScalar::Uint(x) => Ok(i16::try_from(x)?),
746 DmapScalar::Ulong(x) => Ok(i16::try_from(x)?),
747 DmapScalar::Float(x) => Err(DmapError::InvalidScalar(format!(
748 "Unable to convert {x}_f32 to i16"
749 ))),
750 DmapScalar::Double(x) => Err(DmapError::InvalidScalar(format!(
751 "Unable to convert {x}_f64 to i16"
752 ))),
753 DmapScalar::String(x) => Err(DmapError::InvalidScalar(format!(
754 "Unable to convert {x} to i16"
755 ))),
756 }
757 }
758}
759impl TryFrom<DmapScalar> for i32 {
760 type Error = DmapError;
761 fn try_from(value: DmapScalar) -> std::result::Result<Self, Self::Error> {
762 match value {
763 DmapScalar::Char(x) => Ok(x as i32),
764 DmapScalar::Short(x) => Ok(x as i32),
765 DmapScalar::Int(x) => Ok(x),
766 DmapScalar::Long(x) => Ok(i32::try_from(x)?),
767 DmapScalar::Uchar(x) => Ok(x as i32),
768 DmapScalar::Ushort(x) => Ok(x as i32),
769 DmapScalar::Uint(x) => Ok(i32::try_from(x)?),
770 DmapScalar::Ulong(x) => Ok(i32::try_from(x)?),
771 DmapScalar::Float(x) => Err(DmapError::InvalidScalar(format!(
772 "Unable to convert {x}_f32 to i32"
773 ))),
774 DmapScalar::Double(x) => Err(DmapError::InvalidScalar(format!(
775 "Unable to convert {x}_f64 to i32"
776 ))),
777 DmapScalar::String(x) => Err(DmapError::InvalidScalar(format!(
778 "Unable to convert {x} to i32"
779 ))),
780 }
781 }
782}
783impl TryFrom<DmapScalar> for i64 {
784 type Error = DmapError;
785 fn try_from(value: DmapScalar) -> std::result::Result<Self, Self::Error> {
786 match value {
787 DmapScalar::Char(x) => Ok(x as i64),
788 DmapScalar::Short(x) => Ok(x as i64),
789 DmapScalar::Int(x) => Ok(x as i64),
790 DmapScalar::Long(x) => Ok(x),
791 DmapScalar::Uchar(x) => Ok(x as i64),
792 DmapScalar::Ushort(x) => Ok(x as i64),
793 DmapScalar::Uint(x) => Ok(x as i64),
794 DmapScalar::Ulong(x) => Ok(i64::try_from(x)?),
795 DmapScalar::Float(x) => Err(DmapError::InvalidScalar(format!(
796 "Unable to convert {x}_f32 to i64"
797 ))),
798 DmapScalar::Double(x) => Err(DmapError::InvalidScalar(format!(
799 "Unable to convert {x}_f64 to i64"
800 ))),
801 DmapScalar::String(x) => Err(DmapError::InvalidScalar(format!(
802 "Unable to convert {x} to i64"
803 ))),
804 }
805 }
806}
807impl TryFrom<DmapScalar> for f32 {
808 type Error = DmapError;
809 fn try_from(value: DmapScalar) -> std::result::Result<Self, Self::Error> {
810 match value {
811 DmapScalar::Char(x) => Ok(x as f32),
812 DmapScalar::Short(x) => Ok(x as f32),
813 DmapScalar::Int(x) => Ok(x as f32),
814 DmapScalar::Long(x) => Ok(x as f32),
815 DmapScalar::Uchar(x) => Ok(x as f32),
816 DmapScalar::Ushort(x) => Ok(x as f32),
817 DmapScalar::Uint(x) => Ok(x as f32),
818 DmapScalar::Ulong(x) => Ok(x as f32),
819 DmapScalar::Float(x) => Ok(x),
820 DmapScalar::Double(x) => Ok(x as f32),
821 DmapScalar::String(x) => Err(DmapError::InvalidScalar(format!(
822 "Unable to convert {x} to f32"
823 ))),
824 }
825 }
826}
827impl TryFrom<DmapScalar> for f64 {
828 type Error = DmapError;
829 fn try_from(value: DmapScalar) -> std::result::Result<Self, Self::Error> {
830 match value {
831 DmapScalar::Char(x) => Ok(x as f64),
832 DmapScalar::Short(x) => Ok(x as f64),
833 DmapScalar::Int(x) => Ok(x as f64),
834 DmapScalar::Long(x) => Ok(x as f64),
835 DmapScalar::Uchar(x) => Ok(x as f64),
836 DmapScalar::Ushort(x) => Ok(x as f64),
837 DmapScalar::Uint(x) => Ok(x as f64),
838 DmapScalar::Ulong(x) => Ok(x as f64),
839 DmapScalar::Float(x) => Ok(f64::from(x)),
840 DmapScalar::Double(x) => Ok(x),
841 DmapScalar::String(x) => Err(DmapError::InvalidScalar(format!(
842 "Unable to convert {x} to f64"
843 ))),
844 }
845 }
846}
847impl TryFrom<DmapScalar> for String {
848 type Error = DmapError;
849 fn try_from(value: DmapScalar) -> std::result::Result<Self, Self::Error> {
850 match value {
851 DmapScalar::String(x) => Ok(x),
852 x => Err(DmapError::InvalidScalar(format!(
853 "Unable to convert {x} to String"
854 ))),
855 }
856 }
857}
858
859pub fn check_scalar(
866 fields: &IndexMap<String, DmapField>,
867 name: &str,
868 expected_type: &Type,
869) -> Result<()> {
870 match fields.get(name) {
871 Some(DmapField::Scalar(data)) if data.get_type() == *expected_type => Ok(()),
872 Some(DmapField::Scalar(data)) => Err(DmapError::InvalidScalar(format!(
873 "{name} is of type {}, expected {}",
874 data.get_type(),
875 expected_type
876 ))),
877 Some(_) => Err(DmapError::InvalidScalar(format!(
878 "{name} is a vector field"
879 ))),
880 None => Err(DmapError::InvalidScalar(format!("{name} is not in record"))),
881 }
882}
883
884pub fn check_scalar_opt(
889 fields: &IndexMap<String, DmapField>,
890 name: &str,
891 expected_type: &Type,
892) -> Result<()> {
893 match fields.get(name) {
894 Some(DmapField::Scalar(data)) if data.get_type() == *expected_type => Ok(()),
895 Some(DmapField::Scalar(data)) => Err(DmapError::InvalidScalar(format!(
896 "{name} is of type {}, expected {}",
897 data.get_type(),
898 expected_type
899 ))),
900 Some(_) => Err(DmapError::InvalidScalar(format!(
901 "{name} is a vector field"
902 ))),
903 None => Ok(()),
904 }
905}
906
907pub fn check_vector(
914 fields: &IndexMap<String, DmapField>,
915 name: &str,
916 expected_type: &Type,
917) -> Result<()> {
918 match fields.get(name) {
919 Some(DmapField::Vector(data)) if data.get_type() != *expected_type => {
920 Err(DmapError::InvalidVector(format!(
921 "{name} is of type {}, expected {}",
922 data.get_type(),
923 expected_type
924 )))
925 }
926 Some(DmapField::Scalar(_)) => Err(DmapError::InvalidVector(format!(
927 "{name} is a scalar field"
928 ))),
929 None => Err(DmapError::InvalidVector(format!("{name} not in record"))),
930 _ => Ok(()),
931 }
932}
933
934pub fn check_vector_opt(
939 fields: &IndexMap<String, DmapField>,
940 name: &str,
941 expected_type: &Type,
942) -> Result<()> {
943 match fields.get(name) {
944 Some(DmapField::Vector(data)) if data.get_type() != *expected_type => {
945 Err(DmapError::InvalidVector(format!(
946 "{name} is of type {}, expected {}",
947 data.get_type(),
948 expected_type
949 )))
950 }
951 Some(DmapField::Scalar(_)) => Err(DmapError::InvalidVector(format!(
952 "{name} is a scalar field"
953 ))),
954 _ => Ok(()),
955 }
956}
957
958#[inline]
965pub(crate) fn parse_scalar(cursor: &mut Cursor<Vec<u8>>) -> Result<(String, DmapField)> {
966 let (name, data_type) = parse_header(cursor)?;
967 let data: DmapScalar = match data_type {
968 Type::Char => DmapScalar::Char(read_data::<i8>(cursor)?),
969 Type::Short => DmapScalar::Short(read_data::<i16>(cursor)?),
970 Type::Int => DmapScalar::Int(read_data::<i32>(cursor)?),
971 Type::Long => DmapScalar::Long(read_data::<i64>(cursor)?),
972 Type::Uchar => DmapScalar::Uchar(read_data::<u8>(cursor)?),
973 Type::Ushort => DmapScalar::Ushort(read_data::<u16>(cursor)?),
974 Type::Uint => DmapScalar::Uint(read_data::<u32>(cursor)?),
975 Type::Ulong => DmapScalar::Ulong(read_data::<u64>(cursor)?),
976 Type::Float => DmapScalar::Float(read_data::<f32>(cursor)?),
977 Type::Double => DmapScalar::Double(read_data::<f64>(cursor)?),
978 Type::String => DmapScalar::String(read_data::<String>(cursor)?),
979 };
980
981 Ok((name, DmapField::Scalar(data)))
982}
983
984#[inline]
986pub(crate) fn parse_header(cursor: &mut Cursor<Vec<u8>>) -> Result<(String, Type)> {
987 let name = read_data::<String>(cursor).map_err(|e| {
988 DmapError::InvalidField(format!("Invalid name, byte {}: {e}", cursor.position()))
989 })?;
990 let data_type_key = read_data::<i8>(cursor).map_err(|e| {
991 DmapError::InvalidField(format!(
992 "Invalid data type for field '{name}', byte {}: {e}",
993 cursor.position() - i8::size() as u64
994 ))
995 })?;
996 let data_type = Type::from_key(data_type_key)?;
997
998 Ok((name, data_type))
999}
1000
1001pub(crate) fn parse_vector_header(
1009 cursor: &mut Cursor<Vec<u8>>,
1010 record_size: i32,
1011) -> Result<(String, Type, Vec<usize>, i32)> {
1012 let (name, data_type) = parse_header(cursor)?;
1013
1014 let vector_dimension = read_data::<i32>(cursor)?;
1015 if vector_dimension > record_size {
1016 return Err(DmapError::InvalidVector(format!(
1017 "Parsed number of vector dimensions {vector_dimension} for field `{name}` at byte {} are larger \
1018 than record size {record_size}",
1019 cursor.position() - i32::size() as u64,
1020 )));
1021 } else if vector_dimension <= 0 {
1022 return Err(DmapError::InvalidVector(format!(
1023 "Parsed number of vector dimensions {vector_dimension} for field `{name}` at byte {} are zero or \
1024 negative",
1025 cursor.position() - i32::size() as u64,
1026 )));
1027 }
1028
1029 let mut dimensions: Vec<usize> = vec![];
1030 let mut total_elements = 1;
1031 for _ in 0..vector_dimension {
1032 let dim = read_data::<i32>(cursor)?;
1033 if dim <= 0 && name != "slist" {
1034 return Err(DmapError::InvalidVector(format!(
1035 "Vector `{name}` dimension {dim} at byte {} is zero or negative",
1036 cursor.position() - i32::size() as u64,
1037 )));
1038 } else if dim > record_size {
1039 return Err(DmapError::InvalidVector(format!(
1040 "Vector `{name}` dimension {dim} at byte {} exceeds record size {record_size}",
1041 cursor.position() - i32::size() as u64,
1042 )));
1043 }
1044 dimensions.push(usize::try_from(dim)?);
1045 total_elements *= dim;
1046 }
1047 dimensions = dimensions.into_iter().rev().collect(); if total_elements * i32::try_from(data_type.size())? > record_size {
1049 return Err(DmapError::InvalidVector(format!(
1050 "Vector `{name}` size starting at byte {} exceeds record size ({} > {record_size})",
1051 cursor.position() - u64::try_from(vector_dimension)? * u64::try_from(i32::size())?,
1052 total_elements * i32::try_from(data_type.size())?,
1053 )));
1054 }
1055
1056 Ok((name, data_type, dimensions, total_elements))
1057}
1058
1059pub(crate) fn parse_vector(
1068 cursor: &mut Cursor<Vec<u8>>,
1069 record_size: i32,
1070) -> Result<(String, DmapField)> {
1071 let start_position = cursor.position();
1072 let (name, data_type, dimensions, total_elements) = parse_vector_header(cursor, record_size)?;
1073
1074 macro_rules! dmapvec_from_cursor {
1075 ($type:ty, $enum_var:path, $dims:ident, $cursor:ident, $num_elements:ident, $name:ident) => {
1076 $enum_var(
1077 ArrayD::from_shape_vec($dims, read_vector::<$type>($cursor, $num_elements)?)
1078 .map_err(|e| {
1079 DmapError::InvalidVector(format!(
1080 "Could not read in vector field {}: {e}",
1081 $name
1082 ))
1083 })?,
1084 )
1085 };
1086 }
1087 let vector: DmapVec = match data_type {
1088 Type::Char => {
1089 dmapvec_from_cursor!(i8, DmapVec::Char, dimensions, cursor, total_elements, name)
1090 }
1091 Type::Short => dmapvec_from_cursor!(
1092 i16,
1093 DmapVec::Short,
1094 dimensions,
1095 cursor,
1096 total_elements,
1097 name
1098 ),
1099 Type::Int => {
1100 dmapvec_from_cursor!(i32, DmapVec::Int, dimensions, cursor, total_elements, name)
1101 }
1102 Type::Long => {
1103 dmapvec_from_cursor!(i64, DmapVec::Long, dimensions, cursor, total_elements, name)
1104 }
1105 Type::Uchar => {
1106 dmapvec_from_cursor!(u8, DmapVec::Uchar, dimensions, cursor, total_elements, name)
1107 }
1108 Type::Ushort => dmapvec_from_cursor!(
1109 u16,
1110 DmapVec::Ushort,
1111 dimensions,
1112 cursor,
1113 total_elements,
1114 name
1115 ),
1116 Type::Uint => {
1117 dmapvec_from_cursor!(u32, DmapVec::Uint, dimensions, cursor, total_elements, name)
1118 }
1119 Type::Ulong => dmapvec_from_cursor!(
1120 u64,
1121 DmapVec::Ulong,
1122 dimensions,
1123 cursor,
1124 total_elements,
1125 name
1126 ),
1127 Type::Float => dmapvec_from_cursor!(
1128 f32,
1129 DmapVec::Float,
1130 dimensions,
1131 cursor,
1132 total_elements,
1133 name
1134 ),
1135 Type::Double => dmapvec_from_cursor!(
1136 f64,
1137 DmapVec::Double,
1138 dimensions,
1139 cursor,
1140 total_elements,
1141 name
1142 ),
1143 Type::String => {
1144 return Err(DmapError::InvalidVector(format!(
1145 "Invalid type {data_type} for DMAP vector {name}"
1146 )))
1147 }
1148 };
1149
1150 let num_bytes = cursor.position() - start_position;
1151 if num_bytes > u64::try_from(record_size)? {
1152 return Err(DmapError::InvalidVector(format!(
1153 "Vector `{name}` occupies more bytes than record ({num_bytes} > {record_size})"
1154 )));
1155 }
1156
1157 Ok((name, DmapField::Vector(vector)))
1158}
1159
1160fn read_vector<T: DmapType>(cursor: &mut Cursor<Vec<u8>>, num_elements: i32) -> Result<Vec<T>> {
1162 let mut data: Vec<T> = vec![];
1163 for _ in 0..num_elements {
1164 data.push(read_data::<T>(cursor)?);
1165 }
1166 Ok(data)
1167}
1168
1169#[inline]
1171pub(crate) fn read_data<T: DmapType>(cursor: &mut Cursor<Vec<u8>>) -> Result<T> {
1172 let position = usize::try_from(cursor.position())?;
1173 let stream = cursor.get_mut();
1174
1175 if position > stream.len() {
1176 return Err(DmapError::CorruptStream("Cursor extends out of buffer"));
1177 }
1178 if stream.len() - position < T::size() {
1179 return Err(DmapError::CorruptStream(
1180 "Byte offsets into buffer are not properly aligned",
1181 ));
1182 }
1183
1184 let data_size = match T::size() {
1185 0 => {
1186 let mut byte_counter = 0;
1188 while stream[position + byte_counter] != 0 {
1189 byte_counter += 1;
1190 if position + byte_counter >= stream.len() {
1191 return Err(DmapError::CorruptStream("String is improperly terminated"));
1192 }
1193 }
1194 byte_counter + 1
1195 }
1196 x => x,
1197 };
1198 let data: &[u8] = &stream[position..position + data_size];
1199 let parsed_data = T::from_bytes(data)?;
1200
1201 cursor.set_position({ position + data_size } as u64);
1202
1203 Ok(parsed_data)
1204}
1205
1206#[cfg(test)]
1207mod tests {
1208 use super::*;
1209 use numpy::ndarray::array;
1210
1211 #[test]
1212 fn test_read_vec() {
1213 let bytes: Vec<u8> = vec![1, 0, 1, 0];
1214 let mut cursor = Cursor::new(bytes.clone());
1215 let data = read_vector::<u8>(&mut cursor, 4);
1216 assert!(data.is_ok());
1217 assert_eq!(data.unwrap(), vec![1, 0, 1, 0]);
1218
1219 cursor.set_position(0);
1220 let data = read_vector::<u16>(&mut cursor, 2);
1221 assert!(data.is_ok());
1222 assert_eq!(data.unwrap(), vec![1, 1]);
1223
1224 cursor.set_position(0);
1225 let data = read_vector::<i8>(&mut cursor, 4);
1226 assert!(data.is_ok());
1227 assert_eq!(data.unwrap(), vec![1, 0, 1, 0]);
1228
1229 cursor.set_position(0);
1230 let data = read_vector::<i16>(&mut cursor, 2);
1231 assert!(data.is_ok());
1232 assert_eq!(data.unwrap(), vec![1, 1]);
1233 }
1234
1235 #[test]
1236 fn test_read_data() {
1237 let bytes: Vec<u8> = vec![1, 0, 0, 0, 0, 0, 0, 0];
1240 let mut cursor = Cursor::new(bytes);
1241 let data = read_data::<u8>(&mut cursor);
1242 assert!(data.is_ok());
1243 assert_eq!(data.unwrap(), 1);
1244
1245 cursor.set_position(0);
1246 let data = read_data::<u16>(&mut cursor);
1247 assert!(data.is_ok());
1248 assert_eq!(data.unwrap(), 1);
1249
1250 cursor.set_position(0);
1251 let data = read_data::<u32>(&mut cursor);
1252 assert!(data.is_ok());
1253 assert_eq!(data.unwrap(), 1);
1254
1255 cursor.set_position(0);
1256 let data = read_data::<u64>(&mut cursor);
1257 assert!(data.is_ok());
1258 assert_eq!(data.unwrap(), 1);
1259
1260 cursor.set_position(0);
1261 let data = read_data::<i8>(&mut cursor);
1262 assert!(data.is_ok());
1263 assert_eq!(data.unwrap(), 1);
1264
1265 cursor.set_position(0);
1266 let data = read_data::<i16>(&mut cursor);
1267 assert!(data.is_ok());
1268 assert_eq!(data.unwrap(), 1);
1269
1270 cursor.set_position(0);
1271 let data = read_data::<i32>(&mut cursor);
1272 assert!(data.is_ok());
1273 assert_eq!(data.unwrap(), 1);
1274
1275 cursor.set_position(0);
1276 let data = read_data::<i64>(&mut cursor);
1277 assert!(data.is_ok());
1278 assert_eq!(data.unwrap(), 1);
1279
1280 cursor.set_position(1);
1282 let data = read_data::<i64>(&mut cursor);
1283 assert!(data.is_err());
1284
1285 cursor.set_position(4);
1287 let data = read_data::<i64>(&mut cursor);
1288 assert!(data.is_err());
1289
1290 let bytes: Vec<u8> = vec![116, 101, 115, 116, 0]; let mut cursor = Cursor::new(bytes);
1292 let data = read_data::<String>(&mut cursor);
1293 assert!(data.is_ok());
1294 assert_eq!(data.unwrap(), "test".to_string());
1295
1296 let bytes: Vec<u8> = vec![116, 101, 115, 116]; let mut cursor = Cursor::new(bytes);
1298 let data = read_data::<String>(&mut cursor);
1299 assert!(data.is_err());
1300 }
1301
1302 #[test]
1303 fn dmaptype() -> Result<()> {
1304 assert_eq!(i8::size(), 1);
1305 assert_eq!(u8::size(), 1);
1306 assert_eq!(i16::size(), 2);
1307 assert_eq!(u16::size(), 2);
1308 assert_eq!(i32::size(), 4);
1309 assert_eq!(u32::size(), 4);
1310 assert_eq!(f32::size(), 4);
1311 assert_eq!(i64::size(), 8);
1312 assert_eq!(u64::size(), 8);
1313 assert_eq!(f64::size(), 8);
1314
1315 assert_eq!(i8::dmap_type(), Type::Char);
1316 assert_eq!(u8::dmap_type(), Type::Uchar);
1317 assert_eq!(i16::dmap_type(), Type::Short);
1318 assert_eq!(u16::dmap_type(), Type::Ushort);
1319 assert_eq!(i32::dmap_type(), Type::Int);
1320 assert_eq!(u32::dmap_type(), Type::Uint);
1321 assert_eq!(f32::dmap_type(), Type::Float);
1322 assert_eq!(i64::dmap_type(), Type::Long);
1323 assert_eq!(u64::dmap_type(), Type::Ulong);
1324 assert_eq!(f64::dmap_type(), Type::Double);
1325
1326 assert_eq!(vec![1], DmapType::as_bytes(&i8::from_bytes(&[1])?));
1327 assert_eq!(vec![1], DmapType::as_bytes(&u8::from_bytes(&[1])?));
1328 assert_eq!(vec![1, 0], DmapType::as_bytes(&i16::from_bytes(&[1, 0])?));
1329 assert_eq!(vec![1, 0], DmapType::as_bytes(&u16::from_bytes(&[1, 0])?));
1330 assert_eq!(
1331 vec![1, 0, 0, 0],
1332 DmapType::as_bytes(&i32::from_bytes(&[1, 0, 0, 0])?)
1333 );
1334 assert_eq!(
1335 vec![1, 2, 3, 4],
1336 DmapType::as_bytes(&u32::from_bytes(&[1, 2, 3, 4])?)
1337 );
1338 assert_eq!(
1339 vec![1, 0, 0, 0],
1340 DmapType::as_bytes(&f32::from_bytes(&[1, 0, 0, 0])?)
1341 );
1342 assert_eq!(
1343 vec![1, 2, 3, 4, 5, 6, 7, 8],
1344 DmapType::as_bytes(&u64::from_bytes(&[1, 2, 3, 4, 5, 6, 7, 8])?)
1345 );
1346 assert_eq!(
1347 vec![1, 0, 0, 0, 1, 2, 3, 4],
1348 DmapType::as_bytes(&i64::from_bytes(&[1, 0, 0, 0, 1, 2, 3, 4])?)
1349 );
1350 assert_eq!(
1351 vec![1, 2, 3, 4, 4, 32, 2, 1],
1352 DmapType::as_bytes(&f64::from_bytes(&[1, 2, 3, 4, 4, 32, 2, 1])?)
1353 );
1354 Ok(())
1355 }
1356
1357 #[test]
1358 fn types() -> Result<()> {
1359 assert_eq!(Type::from_key(1)?, Type::Char);
1360 assert_eq!(Type::from_key(2)?, Type::Short);
1361 assert_eq!(Type::from_key(3)?, Type::Int);
1362 assert_eq!(Type::from_key(10)?, Type::Long);
1363 assert_eq!(Type::from_key(16)?, Type::Uchar);
1364 assert_eq!(Type::from_key(17)?, Type::Ushort);
1365 assert_eq!(Type::from_key(18)?, Type::Uint);
1366 assert_eq!(Type::from_key(19)?, Type::Ulong);
1367 assert_eq!(Type::from_key(4)?, Type::Float);
1368 assert_eq!(Type::from_key(8)?, Type::Double);
1369 assert_eq!(Type::from_key(9)?, Type::String);
1370 assert!(Type::from_key(-1).is_err());
1371 assert!(Type::from_key(15).is_err());
1372 assert!(Type::from_key(0).is_err());
1373
1374 assert_eq!(Type::Char.key(), 1);
1375 assert_eq!(Type::Short.key(), 2);
1376 assert_eq!(Type::Int.key(), 3);
1377 assert_eq!(Type::Long.key(), 10);
1378 assert_eq!(Type::Uchar.key(), 16);
1379 assert_eq!(Type::Ushort.key(), 17);
1380 assert_eq!(Type::Uint.key(), 18);
1381 assert_eq!(Type::Ulong.key(), 19);
1382 assert_eq!(Type::Float.key(), 4);
1383 assert_eq!(Type::Double.key(), 8);
1384 assert_eq!(Type::String.key(), 9);
1385
1386 assert_eq!(Type::Char.size(), 1);
1387 assert_eq!(Type::Short.size(), 2);
1388 assert_eq!(Type::Int.size(), 4);
1389 assert_eq!(Type::Long.size(), 8);
1390 assert_eq!(Type::Uchar.size(), 1);
1391 assert_eq!(Type::Ushort.size(), 2);
1392 assert_eq!(Type::Uint.size(), 4);
1393 assert_eq!(Type::Ulong.size(), 8);
1394 assert_eq!(Type::Float.size(), 4);
1395 assert_eq!(Type::Double.size(), 8);
1396 assert_eq!(Type::String.size(), 0);
1397
1398 Ok(())
1399 }
1400
1401 #[test]
1402 fn dmapscalar() -> Result<()> {
1403 assert_eq!(DmapScalar::Char(0).get_type(), Type::Char);
1404 assert_eq!(DmapScalar::Short(0).get_type(), Type::Short);
1405 assert_eq!(DmapScalar::Int(0).get_type(), Type::Int);
1406 assert_eq!(DmapScalar::Long(0).get_type(), Type::Long);
1407 assert_eq!(DmapScalar::Uchar(0).get_type(), Type::Uchar);
1408 assert_eq!(DmapScalar::Ushort(0).get_type(), Type::Ushort);
1409 assert_eq!(DmapScalar::Uint(0).get_type(), Type::Uint);
1410 assert_eq!(DmapScalar::Ulong(0).get_type(), Type::Ulong);
1411 assert_eq!(DmapScalar::Float(0.0).get_type(), Type::Float);
1412 assert_eq!(DmapScalar::Double(0.0).get_type(), Type::Double);
1413 assert_eq!(
1414 DmapScalar::String("test".to_string()).get_type(),
1415 Type::String
1416 );
1417
1418 let x = DmapScalar::Char(-1);
1419 assert_eq!(x.cast_as(&Type::Short)?, DmapScalar::Short(-1));
1420 assert!(x.cast_as(&Type::Float).is_ok());
1421 assert!(x.cast_as(&Type::Uchar).is_err());
1422 assert!(x.cast_as(&Type::String).is_err());
1423
1424 let x = DmapScalar::Uchar(255);
1425 assert_eq!(x.cast_as(&Type::Short)?, DmapScalar::Short(255));
1426 assert!(x.cast_as(&Type::Char).is_err());
1427 assert!(x.cast_as(&Type::Float).is_ok());
1428 assert!(x.cast_as(&Type::Uchar).is_ok());
1429 assert!(x.cast_as(&Type::String).is_err());
1430
1431 let x = DmapScalar::Short(256);
1432 assert_eq!(x.cast_as(&Type::Short)?, DmapScalar::Short(256));
1433 assert!(x.cast_as(&Type::Char).is_err());
1434 assert_eq!(x.cast_as(&Type::Ushort)?, DmapScalar::Ushort(256));
1435 assert!(x.cast_as(&Type::Uchar).is_err());
1436 assert!(x.cast_as(&Type::Float).is_ok());
1437 assert!(x.cast_as(&Type::String).is_err());
1438
1439 let x = DmapScalar::Float(1.0);
1440 assert!(x.cast_as(&Type::Double).is_ok());
1441 assert!(x.cast_as(&Type::Char).is_err());
1442 assert!(x.cast_as(&Type::Uchar).is_err());
1443 assert!(x.cast_as(&Type::Float).is_ok());
1444 assert!(x.cast_as(&Type::String).is_err());
1445
1446 let x = DmapScalar::String("test".to_string());
1447 assert!(x.cast_as(&Type::Char).is_err());
1448 assert!(x.cast_as(&Type::Short).is_err());
1449 assert!(x.cast_as(&Type::Int).is_err());
1450 assert!(x.cast_as(&Type::Long).is_err());
1451 assert!(x.cast_as(&Type::Uchar).is_err());
1452 assert!(x.cast_as(&Type::Ushort).is_err());
1453 assert!(x.cast_as(&Type::Uint).is_err());
1454 assert!(x.cast_as(&Type::Ulong).is_err());
1455 assert!(x.cast_as(&Type::Float).is_err());
1456 assert!(x.cast_as(&Type::Double).is_err());
1457
1458 assert_eq!(
1459 DmapScalar::Char(8).as_bytes(),
1460 vec![Type::Char.key() as u8, 8]
1461 );
1462 assert_eq!(
1463 DmapScalar::Short(256).as_bytes(),
1464 vec![Type::Short.key() as u8, 0, 1]
1465 );
1466 assert_eq!(
1467 DmapScalar::Int(256).as_bytes(),
1468 vec![Type::Int.key() as u8, 0, 1, 0, 0]
1469 );
1470 assert_eq!(
1471 DmapScalar::Long(512).as_bytes(),
1472 vec![Type::Long.key() as u8, 0, 2, 0, 0, 0, 0, 0, 0]
1473 );
1474 assert_eq!(
1475 DmapScalar::Uchar(8).as_bytes(),
1476 vec![Type::Uchar.key() as u8, 8]
1477 );
1478 assert_eq!(
1479 DmapScalar::Ushort(256).as_bytes(),
1480 vec![Type::Ushort.key() as u8, 0, 1]
1481 );
1482 assert_eq!(
1483 DmapScalar::Uint(256).as_bytes(),
1484 vec![Type::Uint.key() as u8, 0, 1, 0, 0]
1485 );
1486 assert_eq!(
1487 DmapScalar::Ulong(512).as_bytes(),
1488 vec![Type::Ulong.key() as u8, 0, 2, 0, 0, 0, 0, 0, 0]
1489 );
1490 assert_eq!(
1491 DmapScalar::Float(0.0).as_bytes(),
1492 vec![Type::Float.key() as u8, 0, 0, 0, 0]
1493 );
1494 assert_eq!(
1495 DmapScalar::Double(0.0).as_bytes(),
1496 vec![Type::Double.key() as u8, 0, 0, 0, 0, 0, 0, 0, 0]
1497 );
1498 assert_eq!(
1499 DmapScalar::String("test".to_string()).as_bytes(),
1500 vec![Type::String.key() as u8, 116, 101, 115, 116, 0]
1501 );
1502
1503 Ok(())
1504 }
1505
1506 #[test]
1507 fn dmapvec() -> Result<()> {
1508 let arr = DmapVec::Char(array![0, 1, 2, 3, 4].into_dyn());
1509 assert_eq!(arr.get_type(), Type::Char);
1510 let arr = DmapVec::Uchar(array![0, 1, 2, 3, 4].into_dyn());
1511 assert_eq!(arr.get_type(), Type::Uchar);
1512 let arr = DmapVec::Short(array![0, 1, 2, 3, 4].into_dyn());
1513 assert_eq!(arr.get_type(), Type::Short);
1514 let arr = DmapVec::Ushort(array![0, 1, 2, 3, 4].into_dyn());
1515 assert_eq!(arr.get_type(), Type::Ushort);
1516 let arr = DmapVec::Int(array![0, 1, 2, 3, 4].into_dyn());
1517 assert_eq!(arr.get_type(), Type::Int);
1518 let arr = DmapVec::Uint(array![[0, 1, 2], [3, 4, 5]].into_dyn());
1519 assert_eq!(arr.get_type(), Type::Uint);
1520 let arr = DmapVec::Long(array![0, 1, 2, 3, 4].into_dyn());
1521 assert_eq!(arr.get_type(), Type::Long);
1522 let arr = DmapVec::Ulong(array![0, 1, 2, 3, 4].into_dyn());
1523 assert_eq!(arr.get_type(), Type::Ulong);
1524 let arr = DmapVec::Float(array![0.0, 1.0, 2.0, 3.0, 4.0].into_dyn());
1525 assert_eq!(arr.get_type(), Type::Float);
1526 let arr = DmapVec::Double(array![0.0, 1.0, 2.0, 3.0, 4.0].into_dyn());
1527 assert_eq!(arr.get_type(), Type::Double);
1528
1529 Ok(())
1530 }
1531
1532 #[test]
1533 fn check_fields_in_indexmap() -> Result<()> {
1534 use numpy::ndarray::array;
1535
1536 let mut rec = IndexMap::<String, DmapField>::new();
1537 let res = check_scalar(&rec, "test", &Type::Char);
1538 assert!(res.is_err());
1539 let res = check_scalar_opt(&rec, "test", &Type::Char);
1540 assert!(res.is_ok());
1541 let res = check_vector(&rec, "test", &Type::Char);
1542 assert!(res.is_err());
1543 let res = check_vector_opt(&rec, "test", &Type::Char);
1544 assert!(res.is_ok());
1545
1546 let res = rec.insert("test".to_string(), DmapField::from(1i32));
1547 assert!(res.is_none());
1548 let res = check_scalar(&rec, "test", &Type::Int);
1549 assert!(res.is_ok());
1550 let res = check_scalar_opt(&rec, "test", &Type::Char);
1551 assert!(res.is_err());
1552 let res = check_scalar_opt(&rec, "test", &Type::Int);
1553 assert!(res.is_ok());
1554 let res = check_vector(&rec, "test", &Type::Char);
1555 assert!(res.is_err());
1556 let res = check_vector_opt(&rec, "test", &Type::Char);
1557 assert!(res.is_err());
1558
1559 let test_vec = array![1.0f32, 2.0f32].into_dyn();
1560 let res = rec.insert("test_vec".to_string(), test_vec.into());
1561 assert!(res.is_none());
1562 let res = check_scalar(&rec, "test_vec", &Type::Float);
1563 assert!(res.is_err());
1564 let res = check_scalar_opt(&rec, "test_vec", &Type::Float);
1565 assert!(res.is_err());
1566 let res = check_vector(&rec, "test_vec", &Type::Float);
1567 assert!(res.is_ok());
1568 let res = check_vector(&rec, "test_vec", &Type::Double);
1569 assert!(res.is_err());
1570 let res = check_vector_opt(&rec, "test_vec", &Type::Float);
1571 assert!(res.is_ok());
1572 let res = check_vector_opt(&rec, "test_vec", &Type::Int);
1573 assert!(res.is_err());
1574
1575 Ok(())
1576 }
1577
1578 #[test]
1579 fn test_parse_header() -> Result<()> {
1580 let name: Vec<u8> = vec![116, 101, 115, 116, 0, Type::Char.key() as u8];
1581 let num_bytes = name.len();
1582 let mut cursor = Cursor::new(name);
1583 let res = parse_header(&mut cursor);
1584 assert_eq!(res?, ("test".to_string(), Type::Char));
1585 assert_eq!(cursor.position(), num_bytes as u64);
1586
1587 cursor.set_position(2);
1588 let res = parse_header(&mut cursor);
1589 assert_eq!(res?, ("st".to_string(), Type::Char));
1590
1591 cursor.set_position(5);
1592 let res = parse_scalar(&mut cursor);
1593 assert!(res.is_err());
1594
1595 let name: Vec<u8> = vec![116, 101, 115, 116, Type::Char.key() as u8]; let mut cursor = Cursor::new(name);
1597 let res = parse_header(&mut cursor);
1598 assert!(res.is_err());
1599
1600 Ok(())
1601 }
1602
1603 #[test]
1604 fn test_parse_scalar() -> Result<()> {
1605 let mut name: Vec<u8> = vec![116, 101, 115, 116, 0]; let mut data: Vec<u8> = vec![Type::Char.key() as u8, 25, 56];
1607 name.append(&mut data);
1608 let num_bytes = name.len();
1609 let mut cursor = Cursor::new(name);
1610 let res = parse_scalar(&mut cursor);
1611 assert_eq!(res?, ("test".to_string(), 25i8.into()));
1612 assert_eq!(cursor.position(), (num_bytes - 1) as u64);
1613
1614 cursor.set_position(1);
1615 let res = parse_scalar(&mut cursor);
1616 assert_eq!(res?, ("est".to_string(), 25i8.into()));
1617
1618 cursor.set_position(4);
1619 let res = parse_scalar(&mut cursor);
1620 assert_eq!(res?, ("".to_string(), 25i8.into()));
1621
1622 cursor.set_position(5);
1623 let res = parse_scalar(&mut cursor);
1624 assert!(res.is_err());
1625
1626 let mut name: Vec<u8> = vec![116, 101, 115, 116]; let mut data: Vec<u8> = vec![Type::Char.key() as u8, 25];
1630 name.append(&mut data);
1631 let mut cursor = Cursor::new(name);
1632 let res = parse_scalar(&mut cursor);
1633 assert!(res.is_err());
1634
1635 let mut name: Vec<u8> = vec![116, 101, 115, 116, 0]; let mut data: Vec<u8> = vec![Type::String.key() as u8, 116, 101, 115, 116]; name.append(&mut data);
1639 let mut cursor = Cursor::new(name);
1640 let res = parse_scalar(&mut cursor);
1641 assert!(res.is_err());
1642
1643 let mut name: Vec<u8> = vec![116, 101, 115, 116, 0]; let mut data: Vec<u8> = vec![Type::String.key() as u8, 116, 101, 115, 116, 0]; name.append(&mut data);
1646 let mut cursor = Cursor::new(name);
1647 let res = parse_scalar(&mut cursor);
1648 assert_eq!(res?, ("test".to_string(), "test".to_string().into()));
1649
1650 Ok(())
1651 }
1652
1653 #[test]
1654 fn test_parse_vector() -> Result<()> {
1655 let mut name: Vec<u8> = vec![116, 101, 115, 116, 0]; let mut data: Vec<u8> = vec![Type::Char.key() as u8, 1, 0, 0, 0, 1, 0, 0, 0, 25];
1657 name.append(&mut data);
1658 let num_bytes = name.len();
1659 let mut cursor = Cursor::new(name);
1660 let res = parse_vector(&mut cursor, 15);
1661 assert_eq!(res?, ("test".to_string(), array![25i8].into_dyn().into()));
1662 assert_eq!(cursor.position(), num_bytes as u64);
1663
1664 let mut name: Vec<u8> = vec![116, 101, 115, 116, 0]; let mut data: Vec<u8> = vec![
1666 Type::Char.key() as u8,
1667 2,
1668 0,
1669 0,
1670 0,
1671 3,
1672 0,
1673 0,
1674 0,
1675 2,
1676 0,
1677 0,
1678 0,
1679 1,
1680 2,
1681 3,
1682 4,
1683 5,
1684 6,
1685 ];
1686 name.append(&mut data);
1687 let num_bytes = name.len();
1688 let mut cursor = Cursor::new(name);
1689 let res = parse_vector(&mut cursor, 24);
1690 assert_eq!(
1691 res?,
1692 (
1693 "test".to_string(),
1694 array![[1i8, 2, 3], [4, 5, 6]].into_dyn().into()
1695 )
1696 );
1697 assert_eq!(cursor.position(), num_bytes as u64);
1698
1699 cursor.set_position(0);
1700 let res = parse_vector(&mut cursor, 3);
1701 assert!(res.is_err()); let mut name: Vec<u8> = vec![116, 101, 115, 116, 0]; let mut data: Vec<u8> = vec![
1705 Type::Char.key() as u8,
1706 100,
1707 0,
1708 0,
1709 0,
1710 1,
1711 0,
1712 0,
1713 0,
1714 1,
1715 2,
1716 3,
1717 4,
1718 5,
1719 6,
1720 ];
1721 name.append(&mut data);
1722 let mut cursor = Cursor::new(name);
1723 let res = parse_vector(&mut cursor, 24);
1724 assert!(res.is_err()); Ok(())
1727 }
1728}