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