use arrow::array::{Array, ArrayRef};
use arrow::datatypes::DataType;
use crate::datatype::InfallibleBuild;
use crate::{ColumnError, LogicalType};
impl<L: LogicalType> LogicalType for Option<L> {
const NULLABLE: bool = true;
type Typed = L::Typed;
type Value<'a>
= Option<L::Value<'a>>
where
Self: 'a;
type Owned = Option<L::Owned>;
fn downcast(array: &dyn Array) -> Result<Self::Typed, ColumnError> {
L::downcast(array)
}
#[inline]
fn is_null(typed: &Self::Typed, index: usize) -> bool {
L::is_null(typed, index)
}
#[inline]
unsafe fn is_null_unchecked(typed: &Self::Typed, index: usize) -> bool {
unsafe { L::is_null_unchecked(typed, index) }
}
#[inline]
fn value(typed: &Self::Typed, index: usize) -> Self::Value<'_> {
if L::is_null(typed, index) {
None
} else {
Some(L::value(typed, index))
}
}
#[inline]
unsafe fn value_unchecked(typed: &Self::Typed, index: usize) -> Self::Value<'_> {
if unsafe { L::is_null_unchecked(typed, index) } {
None
} else {
Some(unsafe { L::value_unchecked(typed, index) })
}
}
fn to_owned_value(value: Self::Value<'_>) -> Self::Owned {
value.map(L::to_owned_value)
}
}
impl<L: crate::ConcreteType> crate::ConcreteType for Option<L> {
fn datatype() -> DataType {
L::datatype()
}
fn build(values: impl Iterator<Item = Option<Self::Owned>>) -> Result<ArrayRef, ColumnError> {
L::build(values.map(Option::flatten))
}
}
impl<L: InfallibleBuild> InfallibleBuild for Option<L> {}