Skip to main content

arrow_array/builder/
generic_list_view_builder.rs

1// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: See the NOTICE file distributed with this work for additional information regarding copyright ownership
3// SPDX-FileContributor: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements
4
5use crate::builder::ArrayBuilder;
6use crate::{ArrayRef, GenericListViewArray, OffsetSizeTrait};
7use arrow_buffer::{Buffer, NullBufferBuilder, ScalarBuffer};
8use arrow_schema::{Field, FieldRef};
9use std::any::Any;
10use std::sync::Arc;
11
12/// Builder for [`GenericListViewArray`]
13#[derive(Debug)]
14pub struct GenericListViewBuilder<OffsetSize: OffsetSizeTrait, T: ArrayBuilder> {
15    offsets_builder: Vec<OffsetSize>,
16    sizes_builder: Vec<OffsetSize>,
17    null_buffer_builder: NullBufferBuilder,
18    values_builder: T,
19    field: Option<FieldRef>,
20    current_offset: OffsetSize,
21}
22
23impl<O: OffsetSizeTrait, T: ArrayBuilder + Default> Default for GenericListViewBuilder<O, T> {
24    fn default() -> Self {
25        Self::new(T::default())
26    }
27}
28
29impl<OffsetSize: OffsetSizeTrait, T: ArrayBuilder> ArrayBuilder
30    for GenericListViewBuilder<OffsetSize, T>
31{
32    /// Returns the builder as a non-mutable `Any` reference.
33    fn as_any(&self) -> &dyn Any {
34        self
35    }
36
37    /// Returns the builder as a mutable `Any` reference.
38    fn as_any_mut(&mut self) -> &mut dyn Any {
39        self
40    }
41
42    /// Returns the boxed builder as a box of `Any`.
43    fn into_box_any(self: Box<Self>) -> Box<dyn Any> {
44        self
45    }
46
47    /// Returns the number of array slots in the builder
48    fn len(&self) -> usize {
49        self.null_buffer_builder.len()
50    }
51
52    /// Builds the array and reset this builder.
53    fn finish(&mut self) -> ArrayRef {
54        Arc::new(self.finish())
55    }
56
57    /// Builds the array without resetting the builder.
58    fn finish_cloned(&self) -> ArrayRef {
59        Arc::new(self.finish_cloned())
60    }
61
62    fn finish_preserve_values(&mut self) -> ArrayRef {
63        Arc::new(self.finish_preserve_values())
64    }
65}
66
67impl<OffsetSize: OffsetSizeTrait, T: ArrayBuilder> GenericListViewBuilder<OffsetSize, T> {
68    /// Creates a new [`GenericListViewBuilder`] from a given values array builder
69    pub fn new(values_builder: T) -> Self {
70        let capacity = values_builder.len();
71        Self::with_capacity(values_builder, capacity)
72    }
73
74    /// Creates a new [`GenericListViewBuilder`] from a given values array builder
75    /// `capacity` is the number of items to pre-allocate space for in this builder
76    pub fn with_capacity(values_builder: T, capacity: usize) -> Self {
77        let offsets_builder = Vec::with_capacity(capacity);
78        let sizes_builder = Vec::with_capacity(capacity);
79        Self {
80            offsets_builder,
81            null_buffer_builder: NullBufferBuilder::new(capacity),
82            values_builder,
83            sizes_builder,
84            field: None,
85            current_offset: OffsetSize::zero(),
86        }
87    }
88
89    ///
90    /// By default a nullable field is created with the name `item`
91    ///
92    /// Note: [`Self::finish`] and [`Self::finish_cloned`] will panic if the
93    /// field's data type does not match that of `T`
94    pub fn with_field(self, field: impl Into<FieldRef>) -> Self {
95        Self {
96            field: Some(field.into()),
97            ..self
98        }
99    }
100}
101
102impl<OffsetSize: OffsetSizeTrait, T: ArrayBuilder> GenericListViewBuilder<OffsetSize, T>
103where
104    T: 'static,
105{
106    /// Returns the child array builder as a mutable reference.
107    ///
108    /// This mutable reference can be used to append values into the child array builder,
109    /// but you must call [`append`](#method.append) to delimit each distinct list value.
110    pub fn values(&mut self) -> &mut T {
111        &mut self.values_builder
112    }
113
114    /// Returns the child array builder as an immutable reference
115    pub fn values_ref(&self) -> &T {
116        &self.values_builder
117    }
118
119    /// Finish the current variable-length list array slot
120    ///
121    /// # Panics
122    ///
123    /// Panics if the length of [`Self::values`] exceeds `OffsetSize::MAX`
124    #[inline]
125    pub fn append(&mut self, is_valid: bool) {
126        self.offsets_builder.push(self.current_offset);
127        self.sizes_builder.push(
128            OffsetSize::from_usize(
129                self.values_builder.len() - self.current_offset.to_usize().unwrap(),
130            )
131            .unwrap(),
132        );
133        self.null_buffer_builder.append(is_valid);
134        self.current_offset = OffsetSize::from_usize(self.values_builder.len()).unwrap();
135    }
136
137    /// Append value into this [`GenericListViewBuilder`]
138    #[inline]
139    pub fn append_value<I, V>(&mut self, i: I)
140    where
141        T: Extend<Option<V>>,
142        I: IntoIterator<Item = Option<V>>,
143    {
144        self.extend(std::iter::once(Some(i)))
145    }
146
147    /// Append a null to this [`GenericListViewBuilder`]
148    ///
149    /// See [`Self::append_value`] for an example use.
150    #[inline]
151    pub fn append_null(&mut self) {
152        self.offsets_builder.push(self.current_offset);
153        self.sizes_builder.push(OffsetSize::zero());
154        self.null_buffer_builder.append_null();
155    }
156
157    /// Appends an optional value into this [`GenericListViewBuilder`]
158    ///
159    /// If `Some` calls [`Self::append_value`] otherwise calls [`Self::append_null`]
160    #[inline]
161    pub fn append_option<I, V>(&mut self, i: Option<I>)
162    where
163        T: Extend<Option<V>>,
164        I: IntoIterator<Item = Option<V>>,
165    {
166        match i {
167            Some(i) => self.append_value(i),
168            None => self.append_null(),
169        }
170    }
171
172    /// Builds the [`GenericListViewArray`] and reset this builder.
173    ///
174    /// # Panics
175    ///
176    /// Panics if the field set with [`Self::with_field`] does not match the data type
177    /// of the values builder
178    pub fn finish(&mut self) -> GenericListViewArray<OffsetSize> {
179        let values = self.values_builder.finish();
180        let nulls = self.null_buffer_builder.finish();
181        let offsets = Buffer::from_vec(std::mem::take(&mut self.offsets_builder));
182        self.current_offset = OffsetSize::zero();
183
184        // Safety: Safe by construction
185        let offsets = ScalarBuffer::from(offsets);
186        let sizes = Buffer::from_vec(std::mem::take(&mut self.sizes_builder));
187        let sizes = ScalarBuffer::from(sizes);
188        let field = match &self.field {
189            Some(f) => f.clone(),
190            None => Arc::new(Field::new("item", values.data_type().clone(), true)),
191        };
192        GenericListViewArray::new(field, offsets, sizes, values, nulls)
193    }
194
195    /// Builds the [`GenericListViewArray`] without resetting the builder.
196    ///
197    /// # Panics
198    ///
199    /// Panics if the field set with [`Self::with_field`] does not match the data type
200    /// of the values builder
201    pub fn finish_cloned(&self) -> GenericListViewArray<OffsetSize> {
202        let values = self.values_builder.finish_cloned();
203        let nulls = self.null_buffer_builder.finish_cloned();
204
205        let offsets = Buffer::from_slice_ref(self.offsets_builder.as_slice());
206        // Safety: safe by construction
207        let offsets = ScalarBuffer::from(offsets);
208
209        let sizes = Buffer::from_slice_ref(self.sizes_builder.as_slice());
210        let sizes = ScalarBuffer::from(sizes);
211
212        let field = match &self.field {
213            Some(f) => f.clone(),
214            None => Arc::new(Field::new("item", values.data_type().clone(), true)),
215        };
216
217        GenericListViewArray::new(field, offsets, sizes, values, nulls)
218    }
219
220    fn finish_preserve_values(&mut self) -> GenericListViewArray<OffsetSize> {
221        let values = self.values_builder.finish_preserve_values();
222        let nulls = self.null_buffer_builder.finish();
223        let offsets = Buffer::from_vec(std::mem::take(&mut self.offsets_builder));
224        self.current_offset = OffsetSize::zero();
225
226        // Safety: Safe by construction
227        let offsets = ScalarBuffer::from(offsets);
228        let sizes = Buffer::from_vec(std::mem::take(&mut self.sizes_builder));
229        let sizes = ScalarBuffer::from(sizes);
230        let field = match &self.field {
231            Some(f) => f.clone(),
232            None => Arc::new(Field::new("item", values.data_type().clone(), true)),
233        };
234        GenericListViewArray::new(field, offsets, sizes, values, nulls)
235    }
236
237    /// Returns the current offsets buffer as a slice
238    pub fn offsets_slice(&self) -> &[OffsetSize] {
239        self.offsets_builder.as_slice()
240    }
241}
242
243impl<O, B, V, E> Extend<Option<V>> for GenericListViewBuilder<O, B>
244where
245    O: OffsetSizeTrait,
246    B: ArrayBuilder + Extend<E>,
247    V: IntoIterator<Item = E>,
248{
249    #[inline]
250    fn extend<T: IntoIterator<Item = Option<V>>>(&mut self, iter: T) {
251        for v in iter {
252            match v {
253                Some(elements) => {
254                    self.values_builder.extend(elements);
255                    self.append(true);
256                }
257                None => self.append(false),
258            }
259        }
260    }
261}
262
263#[cfg(test)]
264mod tests {
265    use super::*;
266    use crate::builder::{Int32Builder, ListViewBuilder, make_builder, tests::PreserveValuesMock};
267    use crate::cast::AsArray;
268    use crate::types::Int32Type;
269    use crate::{Array, Int32Array};
270    use arrow_schema::DataType;
271
272    fn test_generic_list_view_array_builder_impl<O: OffsetSizeTrait>() {
273        let values_builder = Int32Builder::with_capacity(10);
274        let mut builder = GenericListViewBuilder::<O, _>::new(values_builder);
275
276        //  [[0, 1, 2], [3, 4, 5], [6, 7]]
277        builder.values().append_value(0);
278        builder.values().append_value(1);
279        builder.values().append_value(2);
280        builder.append(true);
281        builder.values().append_value(3);
282        builder.values().append_value(4);
283        builder.values().append_value(5);
284        builder.append(true);
285        builder.values().append_value(6);
286        builder.values().append_value(7);
287        builder.append(true);
288        let list_array = builder.finish();
289
290        let list_values = list_array.values().as_primitive::<Int32Type>();
291        assert_eq!(list_values.values(), &[0, 1, 2, 3, 4, 5, 6, 7]);
292        assert_eq!(list_array.value_offsets(), [0, 3, 6].map(O::usize_as));
293        assert_eq!(list_array.value_sizes(), [3, 3, 2].map(O::usize_as));
294        assert_eq!(DataType::Int32, list_array.value_type());
295        assert_eq!(3, list_array.len());
296        assert_eq!(0, list_array.null_count());
297        assert_eq!(O::from_usize(6).unwrap(), list_array.value_offsets()[2]);
298        assert_eq!(O::from_usize(2).unwrap(), list_array.value_sizes()[2]);
299        for i in 0..2 {
300            assert!(list_array.is_valid(i));
301            assert!(!list_array.is_null(i));
302        }
303    }
304
305    #[test]
306    fn test_list_view_array_builder() {
307        test_generic_list_view_array_builder_impl::<i32>()
308    }
309
310    #[test]
311    fn test_large_list_view_array_builder() {
312        test_generic_list_view_array_builder_impl::<i64>()
313    }
314
315    fn test_generic_list_view_array_builder_nulls_impl<O: OffsetSizeTrait>() {
316        let values_builder = Int32Builder::with_capacity(10);
317        let mut builder = GenericListViewBuilder::<O, _>::new(values_builder);
318
319        //  [[0, 1, 2], null, [3, null, 5], [6, 7]]
320        builder.values().append_value(0);
321        builder.values().append_value(1);
322        builder.values().append_value(2);
323        builder.append(true);
324        builder.append(false);
325        builder.values().append_value(3);
326        builder.values().append_null();
327        builder.values().append_value(5);
328        builder.append(true);
329        builder.values().append_value(6);
330        builder.values().append_value(7);
331        builder.append(true);
332
333        let list_array = builder.finish();
334
335        assert_eq!(DataType::Int32, list_array.value_type());
336        assert_eq!(4, list_array.len());
337        assert_eq!(1, list_array.null_count());
338        assert_eq!(O::from_usize(3).unwrap(), list_array.value_offsets()[2]);
339        assert_eq!(O::from_usize(3).unwrap(), list_array.value_sizes()[2]);
340    }
341
342    #[test]
343    fn test_list_view_array_builder_nulls() {
344        test_generic_list_view_array_builder_nulls_impl::<i32>()
345    }
346
347    #[test]
348    fn test_large_list_view_array_builder_nulls() {
349        test_generic_list_view_array_builder_nulls_impl::<i64>()
350    }
351
352    #[test]
353    fn test_list_view_array_builder_finish() {
354        let values_builder = Int32Array::builder(5);
355        let mut builder = ListViewBuilder::new(values_builder);
356
357        builder.values().append_slice(&[1, 2, 3]);
358        builder.append(true);
359        builder.values().append_slice(&[4, 5, 6]);
360        builder.append(true);
361
362        let mut arr = builder.finish();
363        assert_eq!(2, arr.len());
364        assert!(builder.is_empty());
365
366        builder.values().append_slice(&[7, 8, 9]);
367        builder.append(true);
368        arr = builder.finish();
369        assert_eq!(1, arr.len());
370        assert!(builder.is_empty());
371    }
372
373    #[test]
374    fn test_list_view_array_builder_finish_cloned() {
375        let values_builder = Int32Array::builder(5);
376        let mut builder = ListViewBuilder::new(values_builder);
377
378        builder.values().append_slice(&[1, 2, 3]);
379        builder.append(true);
380        builder.values().append_slice(&[4, 5, 6]);
381        builder.append(true);
382
383        let mut arr = builder.finish_cloned();
384        assert_eq!(2, arr.len());
385        assert!(!builder.is_empty());
386
387        builder.values().append_slice(&[7, 8, 9]);
388        builder.append(true);
389        arr = builder.finish();
390        assert_eq!(3, arr.len());
391        assert!(builder.is_empty());
392    }
393
394    #[test]
395    fn test_list_view_list_view_array_builder() {
396        let primitive_builder = Int32Builder::with_capacity(10);
397        let values_builder = ListViewBuilder::new(primitive_builder);
398        let mut builder = ListViewBuilder::new(values_builder);
399
400        //  [[[1, 2], [3, 4]], [[5, 6, 7], null, [8]], null, [[9, 10]]]
401        builder.values().values().append_value(1);
402        builder.values().values().append_value(2);
403        builder.values().append(true);
404        builder.values().values().append_value(3);
405        builder.values().values().append_value(4);
406        builder.values().append(true);
407        builder.append(true);
408
409        builder.values().values().append_value(5);
410        builder.values().values().append_value(6);
411        builder.values().values().append_value(7);
412        builder.values().append(true);
413        builder.values().append(false);
414        builder.values().values().append_value(8);
415        builder.values().append(true);
416        builder.append(true);
417
418        builder.append(false);
419
420        builder.values().values().append_value(9);
421        builder.values().values().append_value(10);
422        builder.values().append(true);
423        builder.append(true);
424
425        let l1 = builder.finish();
426
427        assert_eq!(4, l1.len());
428        assert_eq!(1, l1.null_count());
429
430        assert_eq!(l1.value_offsets(), &[0, 2, 5, 5]);
431        assert_eq!(l1.value_sizes(), &[2, 3, 0, 1]);
432
433        let l2 = l1.values().as_list_view::<i32>();
434
435        assert_eq!(6, l2.len());
436        assert_eq!(1, l2.null_count());
437        assert_eq!(l2.value_offsets(), &[0, 2, 4, 7, 7, 8]);
438        assert_eq!(l2.value_sizes(), &[2, 2, 3, 0, 1, 2]);
439
440        let i1 = l2.values().as_primitive::<Int32Type>();
441        assert_eq!(10, i1.len());
442        assert_eq!(0, i1.null_count());
443        assert_eq!(i1.values(), &[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
444    }
445
446    #[test]
447    fn test_extend() {
448        let mut builder = ListViewBuilder::new(Int32Builder::new());
449        builder.extend([
450            Some(vec![Some(1), Some(2), Some(7), None]),
451            Some(vec![]),
452            Some(vec![Some(4), Some(5)]),
453            None,
454        ]);
455
456        let array = builder.finish();
457        assert_eq!(array.value_offsets(), [0, 4, 4, 6]);
458        assert_eq!(array.value_sizes(), [4, 0, 2, 0]);
459        assert_eq!(array.null_count(), 1);
460        assert!(array.is_null(3));
461        let elements = array.values().as_primitive::<Int32Type>();
462        assert_eq!(elements.values(), &[1, 2, 7, 0, 4, 5]);
463        assert_eq!(elements.null_count(), 1);
464        assert!(elements.is_null(3));
465    }
466
467    #[test]
468    fn test_boxed_primitive_array_builder() {
469        let values_builder = make_builder(&DataType::Int32, 5);
470        let mut builder = ListViewBuilder::new(values_builder);
471
472        builder
473            .values()
474            .as_any_mut()
475            .downcast_mut::<Int32Builder>()
476            .expect("should be an Int32Builder")
477            .append_slice(&[1, 2, 3]);
478        builder.append(true);
479
480        builder
481            .values()
482            .as_any_mut()
483            .downcast_mut::<Int32Builder>()
484            .expect("should be an Int32Builder")
485            .append_slice(&[4, 5, 6]);
486        builder.append(true);
487
488        let arr = builder.finish();
489        assert_eq!(2, arr.len());
490
491        let elements = arr.values().as_primitive::<Int32Type>();
492        assert_eq!(elements.values(), &[1, 2, 3, 4, 5, 6]);
493    }
494
495    #[test]
496    fn test_boxed_list_view_list_view_array_builder() {
497        // This test is same as `test_list_list_array_builder` but uses boxed builders.
498        let values_builder = make_builder(
499            &DataType::ListView(Arc::new(Field::new("item", DataType::Int32, true))),
500            10,
501        );
502        test_boxed_generic_list_view_generic_list_view_array_builder::<i32>(values_builder);
503    }
504
505    #[test]
506    fn test_boxed_large_list_view_large_list_view_array_builder() {
507        // This test is same as `test_list_list_array_builder` but uses boxed builders.
508        let values_builder = make_builder(
509            &DataType::LargeListView(Arc::new(Field::new("item", DataType::Int32, true))),
510            10,
511        );
512        test_boxed_generic_list_view_generic_list_view_array_builder::<i64>(values_builder);
513    }
514
515    fn test_boxed_generic_list_view_generic_list_view_array_builder<O>(
516        values_builder: Box<dyn ArrayBuilder>,
517    ) where
518        O: OffsetSizeTrait + PartialEq,
519    {
520        let mut builder: GenericListViewBuilder<O, Box<dyn ArrayBuilder>> =
521            GenericListViewBuilder::<O, Box<dyn ArrayBuilder>>::new(values_builder);
522
523        //  [[[1, 2], [3, 4]], [[5, 6, 7], null, [8]], null, [[9, 10]]]
524        builder
525            .values()
526            .as_any_mut()
527            .downcast_mut::<GenericListViewBuilder<O, Box<dyn ArrayBuilder>>>()
528            .expect("should be an (Large)ListViewBuilder")
529            .values()
530            .as_any_mut()
531            .downcast_mut::<Int32Builder>()
532            .expect("should be an Int32Builder")
533            .append_value(1);
534        builder
535            .values()
536            .as_any_mut()
537            .downcast_mut::<GenericListViewBuilder<O, Box<dyn ArrayBuilder>>>()
538            .expect("should be an (Large)ListViewBuilder")
539            .values()
540            .as_any_mut()
541            .downcast_mut::<Int32Builder>()
542            .expect("should be an Int32Builder")
543            .append_value(2);
544        builder
545            .values()
546            .as_any_mut()
547            .downcast_mut::<GenericListViewBuilder<O, Box<dyn ArrayBuilder>>>()
548            .expect("should be an (Large)ListViewBuilder")
549            .append(true);
550        builder
551            .values()
552            .as_any_mut()
553            .downcast_mut::<GenericListViewBuilder<O, Box<dyn ArrayBuilder>>>()
554            .expect("should be an (Large)ListViewBuilder")
555            .values()
556            .as_any_mut()
557            .downcast_mut::<Int32Builder>()
558            .expect("should be an Int32Builder")
559            .append_value(3);
560        builder
561            .values()
562            .as_any_mut()
563            .downcast_mut::<GenericListViewBuilder<O, Box<dyn ArrayBuilder>>>()
564            .expect("should be an (Large)ListViewBuilder")
565            .values()
566            .as_any_mut()
567            .downcast_mut::<Int32Builder>()
568            .expect("should be an Int32Builder")
569            .append_value(4);
570        builder
571            .values()
572            .as_any_mut()
573            .downcast_mut::<GenericListViewBuilder<O, Box<dyn ArrayBuilder>>>()
574            .expect("should be an (Large)ListViewBuilder")
575            .append(true);
576        builder.append(true);
577
578        builder
579            .values()
580            .as_any_mut()
581            .downcast_mut::<GenericListViewBuilder<O, Box<dyn ArrayBuilder>>>()
582            .expect("should be an (Large)ListViewBuilder")
583            .values()
584            .as_any_mut()
585            .downcast_mut::<Int32Builder>()
586            .expect("should be an Int32Builder")
587            .append_value(5);
588        builder
589            .values()
590            .as_any_mut()
591            .downcast_mut::<GenericListViewBuilder<O, Box<dyn ArrayBuilder>>>()
592            .expect("should be an (Large)ListViewBuilder")
593            .values()
594            .as_any_mut()
595            .downcast_mut::<Int32Builder>()
596            .expect("should be an Int32Builder")
597            .append_value(6);
598        builder
599            .values()
600            .as_any_mut()
601            .downcast_mut::<GenericListViewBuilder<O, Box<dyn ArrayBuilder>>>()
602            .expect("should be an (Large)ListViewBuilder")
603            .values()
604            .as_any_mut()
605            .downcast_mut::<Int32Builder>()
606            .expect("should be an (Large)ListViewBuilder")
607            .append_value(7);
608        builder
609            .values()
610            .as_any_mut()
611            .downcast_mut::<GenericListViewBuilder<O, Box<dyn ArrayBuilder>>>()
612            .expect("should be an (Large)ListViewBuilder")
613            .append(true);
614        builder
615            .values()
616            .as_any_mut()
617            .downcast_mut::<GenericListViewBuilder<O, Box<dyn ArrayBuilder>>>()
618            .expect("should be an (Large)ListViewBuilder")
619            .append(false);
620        builder
621            .values()
622            .as_any_mut()
623            .downcast_mut::<GenericListViewBuilder<O, Box<dyn ArrayBuilder>>>()
624            .expect("should be an (Large)ListViewBuilder")
625            .values()
626            .as_any_mut()
627            .downcast_mut::<Int32Builder>()
628            .expect("should be an Int32Builder")
629            .append_value(8);
630        builder
631            .values()
632            .as_any_mut()
633            .downcast_mut::<GenericListViewBuilder<O, Box<dyn ArrayBuilder>>>()
634            .expect("should be an (Large)ListViewBuilder")
635            .append(true);
636        builder.append(true);
637
638        builder.append(false);
639
640        builder
641            .values()
642            .as_any_mut()
643            .downcast_mut::<GenericListViewBuilder<O, Box<dyn ArrayBuilder>>>()
644            .expect("should be an (Large)ListViewBuilder")
645            .values()
646            .as_any_mut()
647            .downcast_mut::<Int32Builder>()
648            .expect("should be an Int32Builder")
649            .append_value(9);
650        builder
651            .values()
652            .as_any_mut()
653            .downcast_mut::<GenericListViewBuilder<O, Box<dyn ArrayBuilder>>>()
654            .expect("should be an (Large)ListViewBuilder")
655            .values()
656            .as_any_mut()
657            .downcast_mut::<Int32Builder>()
658            .expect("should be an Int32Builder")
659            .append_value(10);
660        builder
661            .values()
662            .as_any_mut()
663            .downcast_mut::<GenericListViewBuilder<O, Box<dyn ArrayBuilder>>>()
664            .expect("should be an (Large)ListViewBuilder")
665            .append(true);
666        builder.append(true);
667
668        let l1 = builder.finish();
669        assert_eq!(4, l1.len());
670        assert_eq!(1, l1.null_count());
671        assert_eq!(l1.value_offsets(), &[0, 2, 5, 5].map(O::usize_as));
672        assert_eq!(l1.value_sizes(), &[2, 3, 0, 1].map(O::usize_as));
673
674        let l2 = l1.values().as_list_view::<O>();
675        assert_eq!(6, l2.len());
676        assert_eq!(1, l2.null_count());
677        assert_eq!(l2.value_offsets(), &[0, 2, 4, 7, 7, 8].map(O::usize_as));
678        assert_eq!(l2.value_sizes(), &[2, 2, 3, 0, 1, 2].map(O::usize_as));
679
680        let i1 = l2.values().as_primitive::<Int32Type>();
681        assert_eq!(10, i1.len());
682        assert_eq!(0, i1.null_count());
683        assert_eq!(i1.values(), &[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
684    }
685
686    #[test]
687    fn test_with_field() {
688        let field = Arc::new(Field::new("bar", DataType::Int32, false));
689        let mut builder = ListViewBuilder::new(Int32Builder::new()).with_field(field.clone());
690        builder.append_value([Some(1), Some(2), Some(3)]);
691        builder.append_null(); // This is fine as nullability refers to nullability of values
692        builder.append_value([Some(4)]);
693        let array = builder.finish();
694        assert_eq!(array.len(), 3);
695        assert_eq!(array.data_type(), &DataType::ListView(field.clone()));
696
697        builder.append_value([Some(4), Some(5)]);
698        let array = builder.finish();
699        assert_eq!(array.data_type(), &DataType::ListView(field));
700        assert_eq!(array.len(), 1);
701    }
702
703    #[test]
704    #[should_panic(
705        expected = r#"Non-nullable field of ListViewArray \"item\" cannot contain nulls"#
706    )]
707    // If a non-nullable type is declared but a null value is used, it will be intercepted by the null check.
708    fn test_checks_nullability() {
709        let field = Arc::new(Field::new("item", DataType::Int32, false));
710        let mut builder = ListViewBuilder::new(Int32Builder::new()).with_field(field.clone());
711        builder.append_value([Some(1), None]);
712        builder.finish();
713    }
714
715    #[test]
716    #[should_panic(expected = "ListViewArray expected data type Int64 got Int32")]
717    // If the declared type does not match the actual appended type, it will be intercepted by type checking in the finish function.
718    fn test_checks_data_type() {
719        let field = Arc::new(Field::new("item", DataType::Int64, false));
720        let mut builder = ListViewBuilder::new(Int32Builder::new()).with_field(field.clone());
721        builder.append_value([Some(1)]);
722        builder.finish();
723    }
724
725    #[test]
726    fn test_finish_preserve_values() {
727        let mut builder = ListViewBuilder::new(PreserveValuesMock::default());
728
729        builder.values().inner.append_value(1);
730        builder.append(true);
731
732        let arr = builder.finish_preserve_values();
733
734        assert_eq!(1, arr.len());
735        assert_eq!(1, builder.values().called);
736    }
737}