use std::collections::HashMap;
use crate::error::{fail, ErrorKind, MarrowError, Result};
#[allow(unused)]
const _: () = {
trait AssertExpectedTraits: Clone + std::fmt::Debug + PartialEq + Send + Sync {}
impl AssertExpectedTraits for DataType {}
};
#[allow(unused)]
const _: () = {
trait AssertExpectedTraits: Clone + std::fmt::Debug + Default + PartialEq + Send + Sync {}
impl AssertExpectedTraits for Field {}
impl AssertExpectedTraits for FieldMeta {}
impl AssertExpectedTraits for MapMeta {}
impl AssertExpectedTraits for RunEndEncodedMeta {}
};
#[derive(Debug, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Field {
pub name: String,
pub data_type: DataType,
pub nullable: bool,
pub metadata: HashMap<String, String>,
}
impl std::default::Default for Field {
fn default() -> Self {
Self {
data_type: DataType::Null,
name: Default::default(),
nullable: Default::default(),
metadata: Default::default(),
}
}
}
#[derive(Clone, Debug, Default, PartialEq, Eq)]
pub struct FieldMeta {
pub name: String,
pub nullable: bool,
pub metadata: HashMap<String, String>,
}
#[allow(unused)]
pub(crate) fn meta_from_field(field: Field) -> FieldMeta {
FieldMeta {
name: field.name,
nullable: field.nullable,
metadata: field.metadata,
}
}
pub(crate) fn field_from_meta(data_type: DataType, meta: FieldMeta) -> Field {
Field {
data_type,
name: meta.name,
nullable: meta.nullable,
metadata: meta.metadata,
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct MapMeta {
pub entries_name: String,
pub sorted: bool,
pub keys: FieldMeta,
pub values: FieldMeta,
}
impl std::default::Default for MapMeta {
fn default() -> Self {
MapMeta {
entries_name: String::from("entries"),
sorted: false,
keys: FieldMeta {
name: String::from("keys"),
nullable: false,
metadata: HashMap::new(),
},
values: FieldMeta {
name: String::from("values"),
nullable: true,
metadata: HashMap::new(),
},
}
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct RunEndEncodedMeta {
pub run_ends_name: String,
pub values: FieldMeta,
}
impl std::default::Default for RunEndEncodedMeta {
fn default() -> Self {
RunEndEncodedMeta {
run_ends_name: String::from("run_ends"),
values: FieldMeta {
name: String::from("values"),
nullable: true,
metadata: HashMap::new(),
},
}
}
}
#[cfg_attr(
// arrow-version: replace: feature = "arrow-{version}",
feature = "arrow-53",
doc = r#"
See also [`arrow::datatypes::DataType`][crate::impl::arrow::datatypes::DataType]
"#,
)]
#[derive(Debug, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[non_exhaustive]
pub enum DataType {
Null,
Boolean,
Int8,
Int16,
Int32,
Int64,
UInt8,
UInt16,
UInt32,
UInt64,
Float16,
Float32,
Float64,
Utf8,
LargeUtf8,
Utf8View,
Binary,
LargeBinary,
BinaryView,
FixedSizeBinary(i32),
Date32,
Date64,
Timestamp(TimeUnit, Option<String>),
Time32(TimeUnit),
Time64(TimeUnit),
Duration(TimeUnit),
Interval(IntervalUnit),
Decimal128(u8, i8),
Struct(Vec<Field>),
List(Box<Field>),
LargeList(Box<Field>),
FixedSizeList(Box<Field>, i32),
Map(Box<Field>, bool),
Dictionary(Box<DataType>, Box<DataType>),
RunEndEncoded(Box<Field>, Box<Field>),
Union(Vec<(i8, Field)>, UnionMode),
}
#[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Ord, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum TimeUnit {
#[allow(missing_docs)]
Second,
#[allow(missing_docs)]
Millisecond,
#[allow(missing_docs)]
Microsecond,
#[allow(missing_docs)]
Nanosecond,
}
impl std::fmt::Display for TimeUnit {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
TimeUnit::Second => write!(f, "Second"),
TimeUnit::Millisecond => write!(f, "Millisecond"),
TimeUnit::Microsecond => write!(f, "Microsecond"),
TimeUnit::Nanosecond => write!(f, "Nanosecond"),
}
}
}
impl std::str::FromStr for TimeUnit {
type Err = MarrowError;
fn from_str(s: &str) -> Result<Self> {
match s {
"Second" => Ok(Self::Second),
"Millisecond" => Ok(Self::Millisecond),
"Microsecond" => Ok(Self::Microsecond),
"Nanosecond" => Ok(Self::Nanosecond),
s => fail!(ErrorKind::ParseError, "Invalid TimeUnit: {s}"),
}
}
}
#[test]
fn time_unit_as_str() {
use std::str::FromStr;
macro_rules! assert_variant {
($variant:ident) => {
assert_eq!((TimeUnit::$variant).to_string(), stringify!($variant));
assert_eq!(
TimeUnit::from_str(stringify!($variant)).unwrap(),
TimeUnit::$variant
);
};
}
assert_variant!(Second);
assert_variant!(Millisecond);
assert_variant!(Microsecond);
assert_variant!(Nanosecond);
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum UnionMode {
Sparse,
Dense,
}
impl std::fmt::Display for UnionMode {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
UnionMode::Sparse => write!(f, "Sparse"),
UnionMode::Dense => write!(f, "Dense"),
}
}
}
impl std::str::FromStr for UnionMode {
type Err = MarrowError;
fn from_str(s: &str) -> Result<Self> {
match s {
"Sparse" => Ok(UnionMode::Sparse),
"Dense" => Ok(UnionMode::Dense),
s => fail!(ErrorKind::ParseError, "Invalid UnionMode: {s}"),
}
}
}
#[test]
fn union_mode_as_str() {
use std::str::FromStr;
macro_rules! assert_variant {
($variant:ident) => {
assert_eq!((UnionMode::$variant).to_string(), stringify!($variant));
assert_eq!(
UnionMode::from_str(stringify!($variant)).unwrap(),
UnionMode::$variant
);
};
}
assert_variant!(Dense);
assert_variant!(Sparse);
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum IntervalUnit {
YearMonth,
DayTime,
MonthDayNano,
}
impl std::fmt::Display for IntervalUnit {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::YearMonth => write!(f, "YearMonth"),
Self::DayTime => write!(f, "DayTime"),
Self::MonthDayNano => write!(f, "MonthDayNano"),
}
}
}
impl std::str::FromStr for IntervalUnit {
type Err = MarrowError;
fn from_str(s: &str) -> Result<Self> {
match s {
"YearMonth" => Ok(Self::YearMonth),
"DayTime" => Ok(Self::DayTime),
"MonthDayNano" => Ok(Self::MonthDayNano),
s => fail!(ErrorKind::ParseError, "Invalid IntervalUnit: {s}"),
}
}
}
#[test]
fn interval_unit() {
use std::str::FromStr;
macro_rules! assert_variant {
($variant:ident) => {
assert_eq!((IntervalUnit::$variant).to_string(), stringify!($variant));
assert_eq!(
IntervalUnit::from_str(stringify!($variant)).unwrap(),
IntervalUnit::$variant
);
};
}
assert_variant!(YearMonth);
assert_variant!(DayTime);
assert_variant!(MonthDayNano);
}