#![allow(missing_docs)]
use rkyv::{Archive, Deserialize, Serialize};
#[derive(Debug, Clone, PartialEq, Archive, Serialize, Deserialize)]
#[rkyv(serialize_bounds(
__S: rkyv::ser::Writer + rkyv::ser::Allocator,
__S::Error: rkyv::rancor::Source,
))]
#[rkyv(deserialize_bounds(__D::Error: rkyv::rancor::Source))]
#[rkyv(bytecheck(bounds(
__C: rkyv::validation::ArchiveContext,
<__C as rkyv::rancor::Fallible>::Error: rkyv::rancor::Source,
)))]
pub enum DType {
Bool,
Int8,
Int16,
Int32,
Int64,
UInt8,
UInt16,
UInt32,
UInt64,
Float32,
Float64,
String,
Binary,
FixedSizeList {
#[rkyv(omit_bounds)]
child: Box<DType>,
size: u32,
},
List {
#[rkyv(omit_bounds)]
child: Box<DType>,
},
TimestampNs,
}
impl DType {
pub fn element_size(&self) -> Option<usize> {
match self {
DType::Bool | DType::Int8 | DType::UInt8 => Some(1),
DType::Int16 | DType::UInt16 => Some(2),
DType::Int32 | DType::UInt32 | DType::Float32 => Some(4),
DType::Int64 | DType::UInt64 | DType::Float64 | DType::TimestampNs => Some(8),
DType::FixedSizeList { child, size } => {
child.element_size().map(|cs| cs * (*size as usize))
}
DType::String | DType::Binary | DType::List { .. } => None,
}
}
pub fn is_variable_length(&self) -> bool {
self.element_size().is_none()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn fixed_element_sizes() {
assert_eq!(DType::Bool.element_size(), Some(1));
assert_eq!(DType::Int8.element_size(), Some(1));
assert_eq!(DType::Int16.element_size(), Some(2));
assert_eq!(DType::Int32.element_size(), Some(4));
assert_eq!(DType::Int64.element_size(), Some(8));
assert_eq!(DType::UInt8.element_size(), Some(1));
assert_eq!(DType::UInt16.element_size(), Some(2));
assert_eq!(DType::UInt32.element_size(), Some(4));
assert_eq!(DType::UInt64.element_size(), Some(8));
assert_eq!(DType::Float32.element_size(), Some(4));
assert_eq!(DType::Float64.element_size(), Some(8));
assert_eq!(DType::TimestampNs.element_size(), Some(8));
}
#[test]
fn variable_length_types() {
assert!(DType::String.is_variable_length());
assert!(DType::Binary.is_variable_length());
assert!(
DType::List {
child: Box::new(DType::Int32)
}
.is_variable_length()
);
}
#[test]
fn fixed_size_list_element_size() {
let dt = DType::FixedSizeList {
child: Box::new(DType::Int16),
size: 3,
};
assert_eq!(dt.element_size(), Some(6));
assert!(!dt.is_variable_length());
}
#[test]
fn nested_fixed_size_list() {
let inner = DType::FixedSizeList {
child: Box::new(DType::UInt8),
size: 4,
};
let outer = DType::FixedSizeList {
child: Box::new(inner),
size: 2,
};
assert_eq!(outer.element_size(), Some(8));
}
#[test]
fn fixed_size_list_with_vlen_child() {
let dt = DType::FixedSizeList {
child: Box::new(DType::String),
size: 3,
};
assert!(dt.is_variable_length());
assert_eq!(dt.element_size(), None);
}
}