use std::collections::{HashMap, HashSet};
use delta_kernel_derive::internal_api;
use crate::schema::{ArrayType, DataType, MapType, StructField, ToSchema};
#[internal_api]
pub(crate) trait ToDataType {
fn to_data_type() -> DataType;
}
impl<T: ToSchema> ToDataType for T {
fn to_data_type() -> DataType {
T::to_schema().into()
}
}
macro_rules! impl_to_data_type {
( $(($rust_type: ty, $data_type: expr)), * ) => {
$(
impl ToDataType for $rust_type {
fn to_data_type() -> DataType {
$data_type
}
}
)*
};
}
impl_to_data_type!(
(String, DataType::STRING),
(i64, DataType::LONG),
(i32, DataType::INTEGER),
(i16, DataType::SHORT),
(char, DataType::BYTE),
(f32, DataType::FLOAT),
(f64, DataType::DOUBLE),
(bool, DataType::BOOLEAN)
);
impl<T: ToDataType> ToDataType for Vec<T> {
fn to_data_type() -> DataType {
ArrayType::new(T::to_data_type(), false).into()
}
}
impl<T: ToDataType> ToDataType for HashSet<T> {
fn to_data_type() -> DataType {
ArrayType::new(T::to_data_type(), false).into()
}
}
impl<K: ToDataType, V: ToDataType> ToDataType for HashMap<K, V> {
fn to_data_type() -> DataType {
MapType::new(K::to_data_type(), V::to_data_type(), false).into()
}
}
impl<K: ToDataType, V: ToDataType> ToDataType for HashMap<K, Option<V>> {
fn to_data_type() -> DataType {
MapType::new(K::to_data_type(), V::to_data_type(), true).into()
}
}
#[internal_api]
pub(crate) trait GetStructField {
fn get_struct_field(name: impl Into<String>) -> StructField;
}
impl<T: ToDataType> GetStructField for T {
fn get_struct_field(name: impl Into<String>) -> StructField {
StructField::not_null(name, T::to_data_type())
}
}
impl<T: ToDataType> GetStructField for Option<T> {
fn get_struct_field(name: impl Into<String>) -> StructField {
StructField::nullable(name, T::to_data_type())
}
}
pub(crate) trait ToNullableContainerType {
fn to_nullable_container_type() -> DataType;
}
impl<K: ToDataType, V: ToDataType> ToNullableContainerType for HashMap<K, V> {
fn to_nullable_container_type() -> DataType {
MapType::new(K::to_data_type(), V::to_data_type(), true).into()
}
}
#[internal_api]
pub(crate) trait GetNullableContainerStructField {
fn get_nullable_container_struct_field(name: impl Into<String>) -> StructField;
}
impl<T: ToNullableContainerType> GetNullableContainerStructField for T {
fn get_nullable_container_struct_field(name: impl Into<String>) -> StructField {
StructField::not_null(name, T::to_nullable_container_type())
}
}
impl<T: ToNullableContainerType> GetNullableContainerStructField for Option<T> {
fn get_nullable_container_struct_field(name: impl Into<String>) -> StructField {
StructField::nullable(name, T::to_nullable_container_type())
}
}