arrow_cast/cast/
structs.rs1use crate::cast::*;
19
20pub(crate) fn cast_struct_to_struct(
21 array: &StructArray,
22 from_fields: Fields,
23 to_fields: Fields,
24 cast_options: &CastOptions,
25) -> Result<ArrayRef, ArrowError> {
26 let fields_match_order = from_fields.len() == to_fields.len()
28 && from_fields
29 .iter()
30 .zip(to_fields.iter())
31 .all(|(f1, f2)| f1.name() == f2.name());
32
33 let fields = if fields_match_order {
34 cast_struct_fields_in_order(array, to_fields.clone(), cast_options)?
36 } else {
37 let all_fields_match_by_name = to_fields.iter().all(|to_field| {
38 from_fields
39 .iter()
40 .any(|from_field| from_field.name() == to_field.name())
41 });
42
43 if all_fields_match_by_name {
44 cast_struct_fields_by_name(array, from_fields.clone(), to_fields.clone(), cast_options)?
46 } else {
47 cast_struct_fields_in_order(array, to_fields.clone(), cast_options)?
49 }
50 };
51
52 let array = StructArray::try_new(to_fields.clone(), fields, array.nulls().cloned())?;
53 Ok(Arc::new(array) as ArrayRef)
54}
55
56fn cast_struct_fields_by_name(
57 array: &StructArray,
58 from_fields: Fields,
59 to_fields: Fields,
60 cast_options: &CastOptions,
61) -> Result<Vec<ArrayRef>, ArrowError> {
62 to_fields
63 .iter()
64 .map(|to_field| {
65 let from_field_idx = from_fields
66 .iter()
67 .position(|from_field| from_field.name() == to_field.name())
68 .unwrap(); let column = array.column(from_field_idx);
70 cast_with_options(column, to_field.data_type(), cast_options)
71 })
72 .collect::<Result<Vec<ArrayRef>, ArrowError>>()
73}
74
75fn cast_struct_fields_in_order(
76 array: &StructArray,
77 to_fields: Fields,
78 cast_options: &CastOptions,
79) -> Result<Vec<ArrayRef>, ArrowError> {
80 array
81 .columns()
82 .iter()
83 .zip(to_fields.iter())
84 .map(|(l, field)| cast_with_options(l, field.data_type(), cast_options))
85 .collect::<Result<Vec<ArrayRef>, ArrowError>>()
86}