1use crate::builder::ArrayBuilder;
19use crate::types::{ByteArrayType, GenericBinaryType, GenericStringType};
20use crate::{Array, ArrayRef, GenericByteArray, OffsetSizeTrait};
21use arrow_buffer::{ArrowNativeType, Buffer, MutableBuffer, NullBufferBuilder, ScalarBuffer};
22use arrow_data::ArrayDataBuilder;
23use arrow_schema::ArrowError;
24use std::any::Any;
25use std::sync::Arc;
26
27pub struct GenericByteBuilder<T: ByteArrayType> {
32 value_builder: Vec<u8>,
33 offsets_builder: Vec<T::Offset>,
34 null_buffer_builder: NullBufferBuilder,
35}
36
37impl<T: ByteArrayType> GenericByteBuilder<T> {
38 pub fn new() -> Self {
40 Self::with_capacity(1024, 1024)
41 }
42
43 pub fn with_capacity(item_capacity: usize, data_capacity: usize) -> Self {
50 let mut offsets_builder = Vec::with_capacity(item_capacity + 1);
51 offsets_builder.push(T::Offset::from_usize(0).unwrap());
52 Self {
53 value_builder: Vec::with_capacity(data_capacity),
54 offsets_builder,
55 null_buffer_builder: NullBufferBuilder::new(item_capacity),
56 }
57 }
58
59 pub unsafe fn new_from_buffer(
69 offsets_buffer: MutableBuffer,
70 mut value_buffer: MutableBuffer,
71 null_buffer: Option<MutableBuffer>,
72 ) -> Self {
73 let offsets_builder: Vec<T::Offset> =
74 ScalarBuffer::<T::Offset>::from(offsets_buffer).into();
75
76 value_buffer.truncate(offsets_builder.last().unwrap().as_usize());
79 let value_builder: Vec<u8> = ScalarBuffer::<u8>::from(value_buffer).into();
80
81 let null_buffer_builder = null_buffer
82 .map(|buffer| NullBufferBuilder::new_from_buffer(buffer, offsets_builder.len() - 1))
83 .unwrap_or_else(|| NullBufferBuilder::new_with_len(offsets_builder.len() - 1));
84
85 Self {
86 offsets_builder,
87 value_builder,
88 null_buffer_builder,
89 }
90 }
91
92 #[inline]
93 fn next_offset(&self) -> T::Offset {
94 T::Offset::from_usize(self.value_builder.len()).expect("byte array offset overflow")
95 }
96
97 #[inline]
113 pub fn append_value(&mut self, value: impl AsRef<T::Native>) {
114 self.value_builder
115 .extend_from_slice(value.as_ref().as_ref());
116 self.null_buffer_builder.append(true);
117 self.offsets_builder.push(self.next_offset());
118 }
119
120 #[inline]
124 pub fn append_value_n(&mut self, value: impl AsRef<T::Native>, n: usize) {
125 let bytes: &[u8] = value.as_ref().as_ref();
126 self.value_builder.reserve(bytes.len() * n);
127 self.offsets_builder.reserve(n);
128 for _ in 0..n {
129 self.value_builder.extend_from_slice(bytes);
130 self.offsets_builder.push(self.next_offset());
131 }
132 self.null_buffer_builder.append_n_non_nulls(n);
133 }
134
135 #[inline]
142 pub fn append_option(&mut self, value: Option<impl AsRef<T::Native>>) {
143 match value {
144 None => self.append_null(),
145 Some(v) => self.append_value(v),
146 };
147 }
148
149 #[inline]
151 pub fn append_null(&mut self) {
152 self.null_buffer_builder.append(false);
153 self.offsets_builder.push(self.next_offset());
154 }
155
156 #[inline]
158 pub fn append_nulls(&mut self, n: usize) {
159 self.null_buffer_builder.append_n_nulls(n);
160 let next_offset = self.next_offset();
161 self.offsets_builder
162 .extend(std::iter::repeat_n(next_offset, n));
163 }
164
165 #[inline]
168 pub fn append_array(&mut self, array: &GenericByteArray<T>) -> Result<(), ArrowError> {
169 use num_traits::CheckedAdd;
170 if array.len() == 0 {
171 return Ok(());
172 }
173
174 let offsets = array.offsets();
175
176 if self.next_offset() == offsets[0] {
179 self.offsets_builder.extend_from_slice(&offsets[1..]);
180 } else {
181 let shift: T::Offset = self.next_offset() - offsets[0];
183
184 if shift.checked_add(&offsets[offsets.len() - 1]).is_none() {
185 return Err(ArrowError::OffsetOverflowError(
186 shift.as_usize() + offsets[offsets.len() - 1].as_usize(),
187 ));
188 }
189
190 self.offsets_builder
191 .extend(offsets[1..].iter().map(|&offset| offset + shift));
192 }
193
194 self.value_builder.extend_from_slice(
196 &array.values().as_slice()[offsets[0].as_usize()..offsets[array.len()].as_usize()],
197 );
198
199 if let Some(null_buffer) = array.nulls() {
200 self.null_buffer_builder.append_buffer(null_buffer);
201 } else {
202 self.null_buffer_builder.append_n_non_nulls(array.len());
203 }
204 Ok(())
205 }
206
207 pub fn finish(&mut self) -> GenericByteArray<T> {
209 let array_type = T::DATA_TYPE;
210 let array_builder = ArrayDataBuilder::new(array_type)
211 .len(self.len())
212 .add_buffer(std::mem::take(&mut self.offsets_builder).into())
213 .add_buffer(std::mem::take(&mut self.value_builder).into())
214 .nulls(self.null_buffer_builder.finish());
215
216 self.offsets_builder.push(self.next_offset());
217 let array_data = unsafe { array_builder.build_unchecked() };
218 GenericByteArray::from(array_data)
219 }
220
221 pub fn finish_cloned(&self) -> GenericByteArray<T> {
223 let array_type = T::DATA_TYPE;
224 let offset_buffer = Buffer::from_slice_ref(self.offsets_builder.as_slice());
225 let value_buffer = Buffer::from_slice_ref(self.value_builder.as_slice());
226 let array_builder = ArrayDataBuilder::new(array_type)
227 .len(self.len())
228 .add_buffer(offset_buffer)
229 .add_buffer(value_buffer)
230 .nulls(self.null_buffer_builder.finish_cloned());
231
232 let array_data = unsafe { array_builder.build_unchecked() };
233 GenericByteArray::from(array_data)
234 }
235
236 pub fn values_slice(&self) -> &[u8] {
238 self.value_builder.as_slice()
239 }
240
241 pub fn values_capacity(&self) -> usize {
243 self.value_builder.capacity()
244 }
245
246 pub fn offsets_slice(&self) -> &[T::Offset] {
248 self.offsets_builder.as_slice()
249 }
250
251 pub fn offsets_capacity(&self) -> usize {
253 self.offsets_builder.capacity()
254 }
255
256 pub fn validity_slice(&self) -> Option<&[u8]> {
258 self.null_buffer_builder.as_slice()
259 }
260
261 pub fn validity_capacity(&self) -> usize {
263 self.null_buffer_builder.allocated_size()
264 }
265
266 pub fn validity_slice_mut(&mut self) -> Option<&mut [u8]> {
268 self.null_buffer_builder.as_slice_mut()
269 }
270}
271
272impl<T: ByteArrayType> std::fmt::Debug for GenericByteBuilder<T> {
273 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
274 write!(f, "{}{}Builder", T::Offset::PREFIX, T::PREFIX)?;
275 f.debug_struct("")
276 .field("value_builder", &self.value_builder)
277 .field("offsets_builder", &self.offsets_builder)
278 .field("null_buffer_builder", &self.null_buffer_builder)
279 .finish()
280 }
281}
282
283impl<T: ByteArrayType> Default for GenericByteBuilder<T> {
284 fn default() -> Self {
285 Self::new()
286 }
287}
288
289impl<T: ByteArrayType> ArrayBuilder for GenericByteBuilder<T> {
290 fn len(&self) -> usize {
292 self.null_buffer_builder.len()
293 }
294
295 fn finish(&mut self) -> ArrayRef {
297 Arc::new(self.finish())
298 }
299
300 fn finish_cloned(&self) -> ArrayRef {
302 Arc::new(self.finish_cloned())
303 }
304
305 fn as_any(&self) -> &dyn Any {
307 self
308 }
309
310 fn as_any_mut(&mut self) -> &mut dyn Any {
312 self
313 }
314
315 fn into_box_any(self: Box<Self>) -> Box<dyn Any> {
317 self
318 }
319}
320
321impl<T: ByteArrayType, V: AsRef<T::Native>> Extend<Option<V>> for GenericByteBuilder<T> {
322 #[inline]
323 fn extend<I: IntoIterator<Item = Option<V>>>(&mut self, iter: I) {
324 for v in iter {
325 self.append_option(v)
326 }
327 }
328}
329
330pub type GenericStringBuilder<O> = GenericByteBuilder<GenericStringType<O>>;
380
381impl<O: OffsetSizeTrait> std::fmt::Write for GenericStringBuilder<O> {
382 fn write_str(&mut self, s: &str) -> std::fmt::Result {
383 self.value_builder.extend_from_slice(s.as_bytes());
384 Ok(())
385 }
386}
387
388const AVERAGE_STRING_LENGTH: usize = 16;
399pub trait StringLikeArrayBuilder: ArrayBuilder {
404 fn type_name() -> &'static str;
406
407 fn with_capacity(capacity: usize) -> Self;
409
410 fn append_value(&mut self, value: &str);
412
413 fn append_null(&mut self);
415}
416
417impl<O: OffsetSizeTrait> StringLikeArrayBuilder for GenericStringBuilder<O> {
418 fn type_name() -> &'static str {
419 std::any::type_name::<Self>()
420 }
421 fn with_capacity(capacity: usize) -> Self {
422 Self::with_capacity(capacity, capacity * AVERAGE_STRING_LENGTH)
423 }
424 fn append_value(&mut self, value: &str) {
425 Self::append_value(self, value);
426 }
427 fn append_null(&mut self) {
428 Self::append_null(self);
429 }
430}
431
432const AVERAGE_BINARY_LENGTH: usize = 128;
443pub trait BinaryLikeArrayBuilder: ArrayBuilder {
448 fn type_name() -> &'static str;
450
451 fn with_capacity(capacity: usize) -> Self;
453
454 fn append_value(&mut self, value: &[u8]);
456
457 fn append_null(&mut self);
459}
460
461impl<O: OffsetSizeTrait> BinaryLikeArrayBuilder for GenericBinaryBuilder<O> {
462 fn type_name() -> &'static str {
463 std::any::type_name::<Self>()
464 }
465 fn with_capacity(capacity: usize) -> Self {
466 Self::with_capacity(capacity, capacity * AVERAGE_BINARY_LENGTH)
467 }
468 fn append_value(&mut self, value: &[u8]) {
469 Self::append_value(self, value);
470 }
471 fn append_null(&mut self) {
472 Self::append_null(self);
473 }
474}
475
476pub type GenericBinaryBuilder<O> = GenericByteBuilder<GenericBinaryType<O>>;
522
523impl<O: OffsetSizeTrait> std::io::Write for GenericBinaryBuilder<O> {
524 fn write(&mut self, bs: &[u8]) -> std::io::Result<usize> {
525 self.value_builder.extend_from_slice(bs);
526 Ok(bs.len())
527 }
528
529 fn flush(&mut self) -> std::io::Result<()> {
530 Ok(())
531 }
532}
533
534#[cfg(test)]
535mod tests {
536 use super::*;
537 use crate::GenericStringArray;
538 use crate::array::Array;
539 use arrow_buffer::NullBuffer;
540 use std::fmt::Write as _;
541 use std::io::Write as _;
542
543 fn _test_generic_binary_builder<O: OffsetSizeTrait>() {
544 let mut builder = GenericBinaryBuilder::<O>::new();
545
546 builder.append_value(b"hello");
547 builder.append_value(b"");
548 builder.append_null();
549 builder.append_value(b"rust");
550
551 let array = builder.finish();
552
553 assert_eq!(4, array.len());
554 assert_eq!(1, array.null_count());
555 assert_eq!(b"hello", array.value(0));
556 assert_eq!([] as [u8; 0], array.value(1));
557 assert!(array.is_null(2));
558 assert_eq!(b"rust", array.value(3));
559 assert_eq!(O::from_usize(5).unwrap(), array.value_offsets()[2]);
560 assert_eq!(O::from_usize(4).unwrap(), array.value_length(3));
561 }
562
563 #[test]
564 fn test_binary_builder() {
565 _test_generic_binary_builder::<i32>()
566 }
567
568 #[test]
569 fn test_large_binary_builder() {
570 _test_generic_binary_builder::<i64>()
571 }
572
573 fn _test_generic_binary_builder_all_nulls<O: OffsetSizeTrait>() {
574 let mut builder = GenericBinaryBuilder::<O>::new();
575 builder.append_null();
576 builder.append_null();
577 builder.append_null();
578 builder.append_nulls(2);
579 assert_eq!(5, builder.len());
580 assert!(!builder.is_empty());
581
582 let array = builder.finish();
583 assert_eq!(5, array.null_count());
584 assert_eq!(5, array.len());
585 assert!(array.is_null(0));
586 assert!(array.is_null(1));
587 assert!(array.is_null(2));
588 assert!(array.is_null(3));
589 assert!(array.is_null(4));
590 }
591
592 #[test]
593 fn test_binary_builder_all_nulls() {
594 _test_generic_binary_builder_all_nulls::<i32>()
595 }
596
597 #[test]
598 fn test_large_binary_builder_all_nulls() {
599 _test_generic_binary_builder_all_nulls::<i64>()
600 }
601
602 fn _test_generic_binary_builder_reset<O: OffsetSizeTrait>() {
603 let mut builder = GenericBinaryBuilder::<O>::new();
604
605 builder.append_value(b"hello");
606 builder.append_value(b"");
607 builder.append_null();
608 builder.append_value(b"rust");
609 builder.finish();
610
611 assert!(builder.is_empty());
612
613 builder.append_value(b"parquet");
614 builder.append_null();
615 builder.append_value(b"arrow");
616 builder.append_value(b"");
617 builder.append_nulls(2);
618 builder.append_value(b"hi");
619 let array = builder.finish();
620
621 assert_eq!(7, array.len());
622 assert_eq!(3, array.null_count());
623 assert_eq!(b"parquet", array.value(0));
624 assert!(array.is_null(1));
625 assert!(array.is_null(4));
626 assert!(array.is_null(5));
627 assert_eq!(b"arrow", array.value(2));
628 assert_eq!(b"", array.value(1));
629 assert_eq!(b"hi", array.value(6));
630
631 assert_eq!(O::zero(), array.value_offsets()[0]);
632 assert_eq!(O::from_usize(7).unwrap(), array.value_offsets()[2]);
633 assert_eq!(O::from_usize(14).unwrap(), array.value_offsets()[7]);
634 assert_eq!(O::from_usize(5).unwrap(), array.value_length(2));
635 }
636
637 #[test]
638 fn test_binary_builder_reset() {
639 _test_generic_binary_builder_reset::<i32>()
640 }
641
642 #[test]
643 fn test_large_binary_builder_reset() {
644 _test_generic_binary_builder_reset::<i64>()
645 }
646
647 fn _test_generic_string_array_builder<O: OffsetSizeTrait>() {
648 let mut builder = GenericStringBuilder::<O>::new();
649 let owned = "arrow".to_owned();
650
651 builder.append_value("hello");
652 builder.append_value("");
653 builder.append_value(&owned);
654 builder.append_null();
655 builder.append_option(Some("rust"));
656 builder.append_option(None::<&str>);
657 builder.append_option(None::<String>);
658 builder.append_nulls(2);
659 builder.append_value("parquet");
660 assert_eq!(10, builder.len());
661
662 assert_eq!(
663 GenericStringArray::<O>::from(vec![
664 Some("hello"),
665 Some(""),
666 Some("arrow"),
667 None,
668 Some("rust"),
669 None,
670 None,
671 None,
672 None,
673 Some("parquet")
674 ]),
675 builder.finish()
676 );
677 }
678
679 #[test]
680 fn test_string_array_builder() {
681 _test_generic_string_array_builder::<i32>()
682 }
683
684 #[test]
685 fn test_large_string_array_builder() {
686 _test_generic_string_array_builder::<i64>()
687 }
688
689 fn _test_generic_string_array_builder_finish<O: OffsetSizeTrait>() {
690 let mut builder = GenericStringBuilder::<O>::with_capacity(3, 11);
691
692 builder.append_value("hello");
693 builder.append_value("rust");
694 builder.append_null();
695
696 builder.finish();
697 assert!(builder.is_empty());
698 assert_eq!(&[O::zero()], builder.offsets_slice());
699
700 builder.append_value("arrow");
701 builder.append_value("parquet");
702 let arr = builder.finish();
703 assert!(arr.nulls().is_none());
705 assert_eq!(GenericStringArray::<O>::from(vec!["arrow", "parquet"]), arr,)
706 }
707
708 #[test]
709 fn test_string_array_builder_finish() {
710 _test_generic_string_array_builder_finish::<i32>()
711 }
712
713 #[test]
714 fn test_large_string_array_builder_finish() {
715 _test_generic_string_array_builder_finish::<i64>()
716 }
717
718 fn _test_generic_string_array_builder_finish_cloned<O: OffsetSizeTrait>() {
719 let mut builder = GenericStringBuilder::<O>::with_capacity(3, 11);
720
721 builder.append_value("hello");
722 builder.append_value("rust");
723 builder.append_null();
724
725 let mut arr = builder.finish_cloned();
726 assert!(!builder.is_empty());
727 assert_eq!(3, arr.len());
728
729 builder.append_value("arrow");
730 builder.append_value("parquet");
731 arr = builder.finish();
732
733 assert!(arr.nulls().is_some());
734 assert_eq!(&[O::zero()], builder.offsets_slice());
735 assert_eq!(5, arr.len());
736 }
737
738 #[test]
739 fn test_string_array_builder_finish_cloned() {
740 _test_generic_string_array_builder_finish_cloned::<i32>()
741 }
742
743 #[test]
744 fn test_large_string_array_builder_finish_cloned() {
745 _test_generic_string_array_builder_finish_cloned::<i64>()
746 }
747
748 #[test]
749 fn test_extend() {
750 let mut builder = GenericStringBuilder::<i32>::new();
751 builder.extend(["a", "b", "c", "", "a", "b", "c"].into_iter().map(Some));
752 builder.extend(["d", "cupcakes", "hello"].into_iter().map(Some));
753 let array = builder.finish();
754 assert_eq!(array.value_offsets(), &[0, 1, 2, 3, 3, 4, 5, 6, 7, 15, 20]);
755 assert_eq!(array.value_data(), b"abcabcdcupcakeshello");
756 }
757
758 #[test]
759 fn test_write_str() {
760 let mut builder = GenericStringBuilder::<i32>::new();
761 write!(builder, "foo").unwrap();
762 builder.append_value("");
763 writeln!(builder, "bar").unwrap();
764 builder.append_value("");
765 write!(builder, "fiz").unwrap();
766 write!(builder, "buz").unwrap();
767 builder.append_value("");
768 let a = builder.finish();
769 let r: Vec<_> = a.iter().flatten().collect();
770 assert_eq!(r, &["foo", "bar\n", "fizbuz"])
771 }
772
773 #[test]
774 fn test_write_bytes() {
775 let mut builder = GenericBinaryBuilder::<i32>::new();
776 write!(builder, "foo").unwrap();
777 builder.append_value("");
778 writeln!(builder, "bar").unwrap();
779 builder.append_value("");
780 write!(builder, "fiz").unwrap();
781 write!(builder, "buz").unwrap();
782 builder.append_value("");
783 let a = builder.finish();
784 let r: Vec<_> = a.iter().flatten().collect();
785 assert_eq!(
786 r,
787 &["foo".as_bytes(), "bar\n".as_bytes(), "fizbuz".as_bytes()]
788 )
789 }
790
791 #[test]
792 fn test_append_array_without_nulls() {
793 let input = vec![
794 "hello", "world", "how", "are", "you", "doing", "today", "I", "am", "doing", "well",
795 "thank", "you", "for", "asking",
796 ];
797 let arr1 = GenericStringArray::<i32>::from(input[..3].to_vec());
798 let arr2 = GenericStringArray::<i32>::from(input[3..7].to_vec());
799 let arr3 = GenericStringArray::<i32>::from(input[7..].to_vec());
800
801 let mut builder = GenericStringBuilder::<i32>::new();
802 builder.append_array(&arr1).unwrap();
803 builder.append_array(&arr2).unwrap();
804 builder.append_array(&arr3).unwrap();
805
806 let actual = builder.finish();
807 let expected = GenericStringArray::<i32>::from(input);
808
809 assert_eq!(actual, expected);
810 }
811
812 #[test]
813 fn test_append_array_with_nulls() {
814 let input = vec![
815 Some("hello"),
816 None,
817 Some("how"),
818 None,
819 None,
820 None,
821 None,
822 Some("I"),
823 Some("am"),
824 Some("doing"),
825 Some("well"),
826 ];
827 let arr1 = GenericStringArray::<i32>::from(input[..3].to_vec());
828 let arr2 = GenericStringArray::<i32>::from(input[3..7].to_vec());
829 let arr3 = GenericStringArray::<i32>::from(input[7..].to_vec());
830
831 let mut builder = GenericStringBuilder::<i32>::new();
832 builder.append_array(&arr1).unwrap();
833 builder.append_array(&arr2).unwrap();
834 builder.append_array(&arr3).unwrap();
835
836 let actual = builder.finish();
837 let expected = GenericStringArray::<i32>::from(input);
838
839 assert_eq!(actual, expected);
840 }
841
842 #[test]
843 fn test_append_empty_array() {
844 let arr = GenericStringArray::<i32>::from(Vec::<&str>::new());
845 let mut builder = GenericStringBuilder::<i32>::new();
846 builder.append_array(&arr).unwrap();
847 let result = builder.finish();
848 assert_eq!(result.len(), 0);
849 }
850
851 #[test]
852 fn test_append_array_with_offset_not_starting_at_0() {
853 let input = vec![
854 Some("hello"),
855 None,
856 Some("how"),
857 None,
858 None,
859 None,
860 None,
861 Some("I"),
862 Some("am"),
863 Some("doing"),
864 Some("well"),
865 ];
866 let full_array = GenericStringArray::<i32>::from(input);
867 let sliced = full_array.slice(1, 4);
868
869 assert_ne!(sliced.offsets()[0].as_usize(), 0);
870 assert_ne!(sliced.offsets().last(), full_array.offsets().last());
871
872 let mut builder = GenericStringBuilder::<i32>::new();
873 builder.append_array(&sliced).unwrap();
874 let actual = builder.finish();
875
876 let expected = GenericStringArray::<i32>::from(vec![None, Some("how"), None, None]);
877
878 assert_eq!(actual, expected);
879 }
880
881 #[test]
882 fn test_append_underlying_null_values_added_as_is() {
883 let input_1_array_with_nulls = {
884 let input = vec![
885 "hello", "world", "how", "are", "you", "doing", "today", "I", "am",
886 ];
887 let (offsets, buffer, _) = GenericStringArray::<i32>::from(input).into_parts();
888
889 GenericStringArray::<i32>::new(
890 offsets,
891 buffer,
892 Some(NullBuffer::from(&[
893 true, false, true, false, false, true, true, true, false,
894 ])),
895 )
896 };
897 let input_2_array_with_nulls = {
898 let input = vec!["doing", "well", "thank", "you", "for", "asking"];
899 let (offsets, buffer, _) = GenericStringArray::<i32>::from(input).into_parts();
900
901 GenericStringArray::<i32>::new(
902 offsets,
903 buffer,
904 Some(NullBuffer::from(&[false, false, true, false, true, true])),
905 )
906 };
907
908 let mut builder = GenericStringBuilder::<i32>::new();
909 builder.append_array(&input_1_array_with_nulls).unwrap();
910 builder.append_array(&input_2_array_with_nulls).unwrap();
911
912 let actual = builder.finish();
913 let expected = GenericStringArray::<i32>::from(vec![
914 Some("hello"),
915 None, Some("how"),
917 None, None, Some("doing"),
920 Some("today"),
921 Some("I"),
922 None, None, None, Some("thank"),
926 None, Some("for"),
928 Some("asking"),
929 ]);
930
931 assert_eq!(actual, expected);
932
933 let expected_underlying_buffer = Buffer::from(
934 [
935 "hello", "world", "how", "are", "you", "doing", "today", "I", "am", "doing",
936 "well", "thank", "you", "for", "asking",
937 ]
938 .join("")
939 .as_bytes(),
940 );
941 assert_eq!(actual.values(), &expected_underlying_buffer);
942 }
943
944 #[test]
945 fn append_array_with_continues_indices() {
946 let input = vec![
947 "hello", "world", "how", "are", "you", "doing", "today", "I", "am", "doing", "well",
948 "thank", "you", "for", "asking",
949 ];
950 let full_array = GenericStringArray::<i32>::from(input);
951 let slice1 = full_array.slice(0, 3);
952 let slice2 = full_array.slice(3, 4);
953 let slice3 = full_array.slice(7, full_array.len() - 7);
954
955 let mut builder = GenericStringBuilder::<i32>::new();
956 builder.append_array(&slice1).unwrap();
957 builder.append_array(&slice2).unwrap();
958 builder.append_array(&slice3).unwrap();
959
960 let actual = builder.finish();
961
962 assert_eq!(actual, full_array);
963 }
964
965 #[test]
966 fn test_append_array_offset_overflow_precise() {
967 let mut builder = GenericStringBuilder::<i32>::new();
968
969 let initial_string = "x".repeat(i32::MAX as usize - 100);
970 builder.append_value(&initial_string);
971
972 let overflow_string = "y".repeat(200);
973 let overflow_array = GenericStringArray::<i32>::from(vec![overflow_string.as_str()]);
974
975 let result = builder.append_array(&overflow_array);
976
977 assert!(matches!(result, Err(ArrowError::OffsetOverflowError(_))));
978 }
979
980 #[test]
981 fn test_append_value_n() {
982 let mut builder = GenericStringBuilder::<i32>::new();
983 builder.append_value("hello");
984 builder.append_value_n("world", 3);
985 builder.append_null();
986 let array = builder.finish();
987
988 assert_eq!(5, array.len());
989 assert_eq!(1, array.null_count());
990 assert_eq!("hello", array.value(0));
991 assert_eq!("world", array.value(1));
992 assert_eq!("world", array.value(2));
993 assert_eq!("world", array.value(3));
994 assert!(array.is_null(4));
995 }
996}