Skip to main content

arrow_array/builder/
generic_list_view_builder.rs

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