Repository: pola-rs/polars
File: crates/polars-core/src/chunked_array/mod.rs (Rust)

Code before:
        width: usize,
        chunks: Vec<ArrayRef>,
        length: usize,
    ) -> Self {
        let dtype = DataType::Array(Box::new(inner_dtype.clone()), width);
        let arrow_dtype = dtype.to_arrow(CompatLevel::newest());
        let field = Arc::new(Field::new(name, dtype));
        if width == 0 {
            use arrow::array::builder::{ArrayBuilder, make_builder};
            let values = make_builder(&inner_dtype.to_arrow(CompatLevel::newest())).freeze();
            return ArrayChunked::new_with_compute_len(
                field,
                vec![FixedSizeListArray::new(arrow_dtype, length, values, None).into_boxed()],
            );
        }

        let chunks = chunks
            .into_iter()
            .map(|chunk| {
                debug_assert_eq!(chunk.len() % width, 0);
                FixedSizeListArray::new(arrow_dtype.clone(), length, chunk, None).into_boxed()
            })
            .collect();

        unsafe { Self::new_with_dims(field, chunks, length, 0) }
    }

    /// Turn the ArrayChunked into the ListChunked with the same items.
    ///
    /// This will always zero copy the values into the ListChunked.
    pub fn to_list(&self) -> ListChunked {
        let inner_dtype = self.inner_dtype();
        let chunks = self
            .downcast_iter()
            .map(|chunk| {
                use arrow::offset::OffsetsBuffer;

                let inner_dtype = chunk.dtype().inner_dtype().unwrap();
                let dtype = inner_dtype.clone().to_large_list(true);

                let offsets = (0..=chunk.len())
                    .map(|i| (i * self.width()) as i64)
                    .collect::<Vec<i64>>();

                // SAFETY: We created our offsets in ascending manner.
                let offsets = unsafe { OffsetsBuffer::new_unchecked(offsets.into()) };

                ListArray::<i64>::new(
                    dtype,
                    offsets,
                    chunk.values().clone(),

Review comment (suggestion):
Let me know if we prefer a hard `assert` or no check at all.

Code after:
        width: usize,
        chunks: Vec<ArrayRef>,
        length: usize,
    ) -> Self {
        let dtype = DataType::Array(Box::new(inner_dtype.clone()), width);
        let arrow_dtype = dtype.to_arrow(CompatLevel::newest());
        let field = Arc::new(Field::new(name, dtype));
        if width == 0 {
            use arrow::array::builder::{ArrayBuilder, make_builder};
            let values = make_builder(&inner_dtype.to_arrow(CompatLevel::newest())).freeze();
            return ArrayChunked::new_with_compute_len(
                field,
                vec![FixedSizeListArray::new(arrow_dtype, length, values, None).into_boxed()],
            );
        }
        let mut total_len = 0;
        let chunks = chunks
            .into_iter()
            .map(|chunk| {
                debug_assert_eq!(chunk.len() % width, 0);
                let chunk_len = chunk.len() / width;
                total_len += chunk_len;
                FixedSizeListArray::new(arrow_dtype.clone(), chunk_len, chunk, None).into_boxed()
            })
            .collect();
        debug_assert_eq!(total_len, length);

        unsafe { Self::new_with_dims(field, chunks, length, 0) }
    }

    /// Turn the ArrayChunked into the ListChunked with the same items.
    ///
    /// This will always zero copy the values into the ListChunked.
    pub fn to_list(&self) -> ListChunked {
        let inner_dtype = self.inner_dtype();
        let chunks = self
            .downcast_iter()
            .map(|chunk| {
                use arrow::offset::OffsetsBuffer;

                let inner_dtype = chunk.dtype().inner_dtype().unwrap();
                let dtype = inner_dtype.clone().to_large_list(true);

                let offsets = (0..=chunk.len())
                    .map(|i| (i * self.width()) as i64)
                    .collect::<Vec<i64>>();

                // SAFETY: We created our offsets in ascending manner.
                let offsets = unsafe { OffsetsBuffer::new_unchecked(offsets.into()) };

                ListArray::<i64>::new(