hdbconnect_arrow/builders/
primitive.rs1use std::sync::Arc;
12
13use arrow_array::ArrayRef;
14use arrow_array::builder::{
15 Float32Builder, Float64Builder, Int16Builder, Int32Builder, Int64Builder, UInt8Builder,
16};
17
18use crate::Result;
19use crate::traits::builder::HanaCompatibleBuilder;
20use crate::traits::sealed::private::Sealed;
21
22macro_rules! impl_primitive_builder {
35 ($name:ident, $builder:ty, $rust_ty:ty, $hana_variant:ident) => {
36 #[derive(Debug)]
40 pub struct $name {
41 builder: $builder,
42 len: usize,
43 }
44
45 impl $name {
46 #[must_use]
48 pub fn new(capacity: usize) -> Self {
49 Self {
50 builder: <$builder>::with_capacity(capacity),
51 len: 0,
52 }
53 }
54
55 #[must_use]
57 pub fn default_capacity() -> Self {
58 Self::new(1024)
59 }
60 }
61
62 impl Sealed for $name {}
63
64 impl HanaCompatibleBuilder for $name {
65 fn append_hana_value(&mut self, value: &hdbconnect::HdbValue) -> Result<()> {
66 use hdbconnect::HdbValue;
67
68 match value {
69 HdbValue::$hana_variant(v) => {
70 let converted: $rust_ty = (*v).try_into().map_err(|e| {
71 crate::ArrowConversionError::value_conversion(
72 stringify!($name),
73 format!("cannot convert {} to {}: {}", v, stringify!($rust_ty), e),
74 )
75 })?;
76 self.builder.append_value(converted);
77 }
78 other => {
79 return Err(crate::ArrowConversionError::value_conversion(
80 stringify!($name),
81 format!("expected {}, got {:?}", stringify!($hana_variant), other),
82 ));
83 }
84 }
85 self.len += 1;
86 Ok(())
87 }
88
89 fn append_null(&mut self) {
90 self.builder.append_null();
91 self.len += 1;
92 }
93
94 fn finish(&mut self) -> ArrayRef {
95 self.len = 0;
96 Arc::new(self.builder.finish())
97 }
98
99 fn len(&self) -> usize {
100 self.len
101 }
102
103 fn capacity(&self) -> Option<usize> {
104 Some(self.builder.capacity())
105 }
106 }
107 };
108}
109
110impl_primitive_builder!(UInt8BuilderWrapper, UInt8Builder, u8, TINYINT);
115impl_primitive_builder!(Int16BuilderWrapper, Int16Builder, i16, SMALLINT);
116impl_primitive_builder!(Int32BuilderWrapper, Int32Builder, i32, INT);
117impl_primitive_builder!(Int64BuilderWrapper, Int64Builder, i64, BIGINT);
118impl_primitive_builder!(Float32BuilderWrapper, Float32Builder, f32, REAL);
119impl_primitive_builder!(Float64BuilderWrapper, Float64Builder, f64, DOUBLE);
120
121#[cfg(test)]
122mod tests {
123 use hdbconnect::HdbValue;
124
125 use super::*;
126
127 #[test]
128 fn test_int32_builder_wrapper() {
129 let mut builder = Int32BuilderWrapper::new(10);
130
131 assert_eq!(builder.len(), 0);
132 assert!(builder.is_empty());
133
134 builder.append_hana_value(&HdbValue::INT(42)).unwrap();
135 builder.append_null();
136 builder.append_hana_value(&HdbValue::INT(-100)).unwrap();
137
138 assert_eq!(builder.len(), 3);
139
140 let array = builder.finish();
141 assert_eq!(array.len(), 3);
142 assert_eq!(builder.len(), 0); }
144
145 #[test]
146 fn test_float64_builder_wrapper() {
147 let mut builder = Float64BuilderWrapper::new(5);
148
149 builder.append_hana_value(&HdbValue::DOUBLE(3.14)).unwrap();
150 builder.append_null();
151
152 let array = builder.finish();
153 assert_eq!(array.len(), 2);
154 }
155
156 #[test]
157 fn test_uint8_builder_wrapper() {
158 let mut builder = UInt8BuilderWrapper::new(5);
159
160 builder.append_hana_value(&HdbValue::TINYINT(255)).unwrap();
161 let array = builder.finish();
162 assert_eq!(array.len(), 1);
163 }
164
165 #[test]
166 fn test_capacity_hint() {
167 let builder = Int32BuilderWrapper::new(100);
168 assert_eq!(builder.capacity(), Some(100));
169 }
170}