typed_arrow/bridge/
decimals.rs1use arrow_array::{
4 Array, Decimal128Array, Decimal256Array,
5 builder::{Decimal128Builder, Decimal256Builder},
6};
7use arrow_buffer::i256;
8use arrow_schema::DataType;
9
10use super::ArrowBinding;
11#[cfg(feature = "views")]
12use super::ArrowBindingView;
13
14pub struct Decimal128<const P: u8, const S: i8>(i128);
17impl<const P: u8, const S: i8> Decimal128<P, S> {
18 #[inline]
20 #[must_use]
21 pub fn new(value: i128) -> Self {
22 Self(value)
23 }
24 #[inline]
26 #[must_use]
27 pub fn value(&self) -> i128 {
28 self.0
29 }
30 #[inline]
32 #[must_use]
33 pub fn into_value(self) -> i128 {
34 self.0
35 }
36}
37
38impl<const P: u8, const S: i8> ArrowBinding for Decimal128<P, S> {
39 type Builder = Decimal128Builder;
40 type Array = Decimal128Array;
41
42 fn data_type() -> DataType {
43 DataType::Decimal128(P, S)
44 }
45
46 fn new_builder(capacity: usize) -> Self::Builder {
47 Decimal128Builder::with_capacity(capacity).with_data_type(DataType::Decimal128(P, S))
48 }
49
50 fn append_value(b: &mut Self::Builder, v: &Self) {
51 b.append_value(v.0);
52 }
53
54 fn append_null(b: &mut Self::Builder) {
55 b.append_null();
56 }
57
58 fn finish(mut b: Self::Builder) -> Self::Array {
59 b.finish()
60 }
61}
62
63#[cfg(feature = "views")]
64impl<const P: u8, const S: i8> ArrowBindingView for Decimal128<P, S> {
65 type Array = Decimal128Array;
66 type View<'a> = Decimal128<P, S>;
67
68 fn get_view(
69 array: &Self::Array,
70 index: usize,
71 ) -> Result<Self::View<'_>, crate::schema::ViewAccessError> {
72 if index >= array.len() {
73 return Err(crate::schema::ViewAccessError::OutOfBounds {
74 index,
75 len: array.len(),
76 field_name: None,
77 });
78 }
79 if array.is_null(index) {
80 return Err(crate::schema::ViewAccessError::UnexpectedNull {
81 index,
82 field_name: None,
83 });
84 }
85 Ok(Decimal128::new(array.value(index)))
86 }
87}
88
89pub struct Decimal256<const P: u8, const S: i8>(i256);
92impl<const P: u8, const S: i8> Decimal256<P, S> {
93 #[inline]
95 #[must_use]
96 pub fn new(value: i256) -> Self {
97 Self(value)
98 }
99 #[inline]
101 #[must_use]
102 pub fn value(&self) -> i256 {
103 self.0
104 }
105 #[inline]
107 #[must_use]
108 pub fn into_value(self) -> i256 {
109 self.0
110 }
111}
112
113impl<const P: u8, const S: i8> ArrowBinding for Decimal256<P, S> {
114 type Builder = Decimal256Builder;
115 type Array = Decimal256Array;
116
117 fn data_type() -> DataType {
118 DataType::Decimal256(P, S)
119 }
120
121 fn new_builder(capacity: usize) -> Self::Builder {
122 Decimal256Builder::with_capacity(capacity).with_data_type(DataType::Decimal256(P, S))
123 }
124
125 fn append_value(b: &mut Self::Builder, v: &Self) {
126 b.append_value(v.0);
127 }
128
129 fn append_null(b: &mut Self::Builder) {
130 b.append_null();
131 }
132
133 fn finish(mut b: Self::Builder) -> Self::Array {
134 b.finish()
135 }
136}
137
138#[cfg(feature = "views")]
139impl<const P: u8, const S: i8> ArrowBindingView for Decimal256<P, S> {
140 type Array = Decimal256Array;
141 type View<'a> = Decimal256<P, S>;
142
143 fn get_view(
144 array: &Self::Array,
145 index: usize,
146 ) -> Result<Self::View<'_>, crate::schema::ViewAccessError> {
147 if index >= array.len() {
148 return Err(crate::schema::ViewAccessError::OutOfBounds {
149 index,
150 len: array.len(),
151 field_name: None,
152 });
153 }
154 if array.is_null(index) {
155 return Err(crate::schema::ViewAccessError::UnexpectedNull {
156 index,
157 field_name: None,
158 });
159 }
160 Ok(Decimal256::new(array.value(index)))
161 }
162}