arrow_cast/cast/
structs.rs1use crate::cast::*;
6
7pub(crate) fn cast_struct_to_struct(
8 array: &StructArray,
9 from_fields: Fields,
10 to_fields: Fields,
11 cast_options: &CastOptions,
12) -> Result<ArrayRef, ArrowError> {
13 let fields_match_order = from_fields.len() == to_fields.len()
15 && from_fields
16 .iter()
17 .zip(to_fields.iter())
18 .all(|(f1, f2)| f1.name() == f2.name());
19
20 let fields = if fields_match_order {
21 cast_struct_fields_in_order(array, to_fields.clone(), cast_options)?
23 } else {
24 let all_fields_match_by_name = to_fields.iter().all(|to_field| {
25 from_fields
26 .iter()
27 .any(|from_field| from_field.name() == to_field.name())
28 });
29
30 if all_fields_match_by_name {
31 cast_struct_fields_by_name(array, from_fields.clone(), to_fields.clone(), cast_options)?
33 } else {
34 cast_struct_fields_in_order(array, to_fields.clone(), cast_options)?
36 }
37 };
38
39 let array = StructArray::try_new(to_fields.clone(), fields, array.nulls().cloned())?;
40 Ok(Arc::new(array) as ArrayRef)
41}
42
43fn cast_struct_fields_by_name(
44 array: &StructArray,
45 from_fields: Fields,
46 to_fields: Fields,
47 cast_options: &CastOptions,
48) -> Result<Vec<ArrayRef>, ArrowError> {
49 to_fields
50 .iter()
51 .map(|to_field| {
52 let from_field_idx = from_fields
53 .iter()
54 .position(|from_field| from_field.name() == to_field.name())
55 .unwrap(); let column = array.column(from_field_idx);
57 cast_with_options(column, to_field.data_type(), cast_options)
58 })
59 .collect::<Result<Vec<ArrayRef>, ArrowError>>()
60}
61
62fn cast_struct_fields_in_order(
63 array: &StructArray,
64 to_fields: Fields,
65 cast_options: &CastOptions,
66) -> Result<Vec<ArrayRef>, ArrowError> {
67 array
68 .columns()
69 .iter()
70 .zip(to_fields.iter())
71 .map(|(l, field)| cast_with_options(l, field.data_type(), cast_options))
72 .collect::<Result<Vec<ArrayRef>, ArrowError>>()
73}