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