#[cfg(feature = "views")]
use arrow_array::Array;
use arrow_array::{
Decimal128Array, Decimal256Array,
builder::{Decimal128Builder, Decimal256Builder},
};
use arrow_buffer::i256;
use arrow_schema::DataType;
use super::ArrowBinding;
#[cfg(feature = "views")]
use super::ArrowBindingView;
#[derive(Debug, Clone, PartialEq)]
pub struct Decimal128<const P: u8, const S: i8>(i128);
impl<const P: u8, const S: i8> Decimal128<P, S> {
#[inline]
#[must_use]
pub fn new(value: i128) -> Self {
Self(value)
}
#[inline]
#[must_use]
pub fn value(&self) -> i128 {
self.0
}
#[inline]
#[must_use]
pub fn into_value(self) -> i128 {
self.0
}
}
#[cfg(feature = "serde")]
impl<'de, const P: u8, const S: i8> serde::de::Deserialize<'de> for Decimal128<P, S> {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::de::Deserializer<'de>,
{
Ok(Self(i128::deserialize(deserializer)?))
}
}
#[cfg(feature = "serde")]
impl<const P: u8, const S: i8> serde::Serialize for Decimal128<P, S> {
fn serialize<S2: serde::Serializer>(&self, serializer: S2) -> Result<S2::Ok, S2::Error> {
self.0.serialize(serializer)
}
}
impl<const P: u8, const S: i8> ArrowBinding for Decimal128<P, S> {
type Builder = Decimal128Builder;
type Array = Decimal128Array;
fn data_type() -> DataType {
DataType::Decimal128(P, S)
}
fn new_builder(capacity: usize) -> Self::Builder {
Decimal128Builder::with_capacity(capacity).with_data_type(DataType::Decimal128(P, S))
}
fn append_value(b: &mut Self::Builder, v: &Self) {
b.append_value(v.0);
}
fn append_null(b: &mut Self::Builder) {
b.append_null();
}
fn finish(mut b: Self::Builder) -> Self::Array {
b.finish()
}
}
#[cfg(feature = "views")]
impl<const P: u8, const S: i8> ArrowBindingView for Decimal128<P, S> {
type Array = Decimal128Array;
type View<'a> = Decimal128<P, S>;
fn get_view(
array: &Self::Array,
index: usize,
) -> Result<Self::View<'_>, crate::schema::ViewAccessError> {
if index >= array.len() {
return Err(crate::schema::ViewAccessError::OutOfBounds {
index,
len: array.len(),
field_name: None,
});
}
if array.is_null(index) {
return Err(crate::schema::ViewAccessError::UnexpectedNull {
index,
field_name: None,
});
}
Ok(Decimal128::new(array.value(index)))
}
}
pub struct Decimal256<const P: u8, const S: i8>(i256);
impl<const P: u8, const S: i8> Decimal256<P, S> {
#[inline]
#[must_use]
pub fn new(value: i256) -> Self {
Self(value)
}
#[inline]
#[must_use]
pub fn value(&self) -> i256 {
self.0
}
#[inline]
#[must_use]
pub fn into_value(self) -> i256 {
self.0
}
}
impl<const P: u8, const S: i8> ArrowBinding for Decimal256<P, S> {
type Builder = Decimal256Builder;
type Array = Decimal256Array;
fn data_type() -> DataType {
DataType::Decimal256(P, S)
}
fn new_builder(capacity: usize) -> Self::Builder {
Decimal256Builder::with_capacity(capacity).with_data_type(DataType::Decimal256(P, S))
}
fn append_value(b: &mut Self::Builder, v: &Self) {
b.append_value(v.0);
}
fn append_null(b: &mut Self::Builder) {
b.append_null();
}
fn finish(mut b: Self::Builder) -> Self::Array {
b.finish()
}
}
#[cfg(feature = "views")]
impl<const P: u8, const S: i8> ArrowBindingView for Decimal256<P, S> {
type Array = Decimal256Array;
type View<'a> = Decimal256<P, S>;
fn get_view(
array: &Self::Array,
index: usize,
) -> Result<Self::View<'_>, crate::schema::ViewAccessError> {
if index >= array.len() {
return Err(crate::schema::ViewAccessError::OutOfBounds {
index,
len: array.len(),
field_name: None,
});
}
if array.is_null(index) {
return Err(crate::schema::ViewAccessError::UnexpectedNull {
index,
field_name: None,
});
}
Ok(Decimal256::new(array.value(index)))
}
}