Repository: pola-rs/polars
File: crates/polars-ops/src/chunked_array/binary/namespace.rs (Rust)

Code before:
        dtype: &DataType,
        is_little_endian: bool,
    ) -> PolarsResult<Vec<Box<dyn Array>>> {
        let ca = self.as_binary();

        match dtype.to_arrow(CompatLevel::newest()).to_physical_type() {
            PhysicalType::Primitive(ty) => {
                let arrow_data_type = dtype.to_arrow(CompatLevel::newest());
                with_match_primitive_type!(ty, |$T| {
                    unsafe {
                        ca.chunks().iter().map(|chunk| {
                            cast_binview_to_primitive_dyn::<$T>(
                                &**chunk,
                                &arrow_data_type,
                                is_little_endian,
                            )
                        }).collect()
                    }
                })
            },
            #[cfg(feature = "dtype-array")]
            PhysicalType::FixedSizeList => {
                // We do the conversion for Arrays using a linear version of the dtype,
                // and then later reshape into the correct size.
                let linear_dtype = if let Some(ref shape) = dtype.get_shape() {
                    &DataType::Array(Box::new(dtype.leaf_dtype().clone()), shape.iter().product())
                } else {
                    dtype
                };
                let arrow_data_type = linear_dtype.to_arrow(CompatLevel::newest());

                let leaf_dtype = dtype.leaf_dtype();
                let leaf_physical_type = leaf_dtype
                    .to_arrow(CompatLevel::newest())
                    .to_physical_type();
                polars_ensure!(
                    dtype.byte_size().is_some() && leaf_physical_type.is_primitive(),
                    InvalidOperation:
                    "unsupported data type in from_buffer. Only numerical types are allowed in arrays."
                );
                let PhysicalType::Primitive(primitive_type) = leaf_physical_type else {
                    panic!("Shouldn't ever be reached.")
                };
                let element_size = leaf_dtype.byte_size().unwrap();

                let result: Vec<ArrayRef> = with_match_primitive_type!(primitive_type, |$T| {
                    unsafe {
                        ca.chunks().iter().map(|chunk| {
                            cast_binview_to_array_primitive_dyn::<$T>(
                                &**chunk,
                                &arrow_data_type,

Review comment (suggestion):
There needs to be proper upfront validation here that the datatype is a `FixedSIzeList` at all nesting levels, otherwise it is prone to panics. `get_shape()` and `leaf_dtype()` are not sufficient (`leaf_dtype()` for example will also traverse into `List` types, and `get_shape()` does not ensure it stops at a primitive type). A test case to cover this would be to cast from an `array[list[T], _]`

I would recommend a dedicated function for this that returns the leaf dtype and flattened width.


Code after:
        match dtype {
            dtype if dtype.is_primitive_numeric() || dtype.is_temporal() => {
                let dtype = dtype.to_physical();
                let arrow_data_type = dtype
                    .to_arrow(CompatLevel::newest())
                    .underlying_physical_type();
                with_match_physical_numeric_polars_type!(dtype, |$T| {
                    unsafe {
                        ca.chunks().iter().map(|chunk| {
                            binview_to_primitive_dyn::<<$T as PolarsNumericType>::Native>(
                                &**chunk,
                                &arrow_data_type,
                                is_little_endian,
                            )
                        }).collect()
                    }
                })
            },
            #[cfg(feature = "dtype-array")]
            DataType::Array(inner_dtype, array_width)
                if inner_dtype.is_primitive_numeric() || inner_dtype.is_temporal() =>
            {
                let inner_dtype = inner_dtype.to_physical();
                let result: Vec<ArrayRef> = with_match_physical_numeric_polars_type!(inner_dtype, |$T| {
                    unsafe {
                        ca.chunks().iter().map(|chunk| {
                            binview_to_fixed_size_list_dyn::<<$T as PolarsNumericType>::Native>(
                                &**chunk,
                                *array_width,
                                is_little_endian
                            )
                        }).collect::<Result<Vec<ArrayRef>, _>>()
                    }
                })?;
                Ok(result)
            },
            _ => Err(
                polars_err!(InvalidOperation: "unsupported data type {:?} in reinterpret. Only numeric or temporal types, or Arrays of those, are allowed.", dtype),
            ),
        }
    }
}

impl BinaryNameSpaceImpl for BinaryChunked {}