1use std::{collections::HashMap, sync::Arc};
2
3use crate::prelude::*;
4
5use arrow_array::*;
6use arrow_buffer::*;
7use arrow_data::*;
8use arrow_schema::*;
9
10pub fn make_union_fields(name: impl Into<String>, fields: Vec<Field>) -> Field {
12 Field::new(
13 name,
14 DataType::Union(
15 UnionFields::new(0..fields.len() as i8, fields),
16 UnionMode::Dense,
17 ),
18 false,
19 )
20}
21
22pub fn unpack_union(data: ArrayData) -> (HashMap<String, usize>, Vec<ArrayRef>) {
24 let (fields, _, _, children) = UnionArray::from(data).into_parts();
25
26 let map = fields
27 .iter()
28 .map(|(id, field)| (field.name().into(), id as usize))
29 .collect::<HashMap<String, usize>>();
30
31 (map, children)
32}
33
34pub fn extract_union_data<T: ArrowMessage>(
36 field: &str,
37 map: &HashMap<String, usize>,
38 children: &[ArrayRef],
39) -> Result<T> {
40 T::try_from_arrow(
41 children
42 .get(
43 *map.get(field)
44 .ok_or(eyre::eyre!("Field {} not found", field))?,
45 )
46 .ok_or(eyre::eyre!("Field {} not found", field))?
47 .into_data(),
48 )
49}
50
51pub fn get_union_fields<T: ArrowMessage>() -> Result<UnionFields> {
53 match T::field("").data_type() {
54 DataType::Union(fields, _) => Ok(fields.clone()),
55 _ => Err(eyre::eyre!("Expected Union data type")),
56 }
57}
58
59pub fn make_union_array(union_fields: UnionFields, children: Vec<ArrayRef>) -> Result<ArrayRef> {
61 UnionArray::try_new(
62 union_fields,
63 ScalarBuffer::from(vec![]),
64 Some(ScalarBuffer::from(vec![])),
65 children,
66 )
67 .map(|union| Arc::new(union) as ArrayRef)
68 .map_err(eyre::Report::msg)
69}