Skip to main content

df_interchange/
from_arrow.rs

1use paste::paste;
2use std::mem::transmute;
3
4use crate::{error::InterchangeError, ArrowArray, ArrowSchema, Interchange};
5
6macro_rules! arrow_to_ffi {
7    ($from_ver:literal) => {
8        paste! {
9            impl Interchange {
10                #[doc = "Move Arrow version `" $from_ver "` to the Arrow data interchange format."]
11                pub fn [<from_arrow_ $from_ver>](df: Vec<[<arrow_crate_ $from_ver>]::record_batch::RecordBatch>) -> Result<Self, InterchangeError> {
12                    Ok(Self {
13                        chunks_aligned: true,
14                        ffi: {
15                            // Number of chunks
16                            let num_chunks = df.len();
17
18                            // Number of columns
19                            let num_cols = df[0].num_columns();
20
21                            // Prepare ffi series vec
22                            let mut ffi: Vec<(String, Vec<(ArrowArray, ArrowSchema)>)> = Vec::with_capacity(num_cols);
23
24                            for c in 0..num_cols {
25                                ffi.push((df[0].schema().field(c).name().clone(), Vec::with_capacity(num_chunks)));
26                            }
27
28                            for chunk in df {
29
30                                for (col_num, col) in chunk.columns().iter().enumerate() {
31
32                                    // Convert to ArrayData
33                                    let array = col.to_data();
34
35                                    // Convert to ffi
36                                    let ffi_schema = [<arrow_crate_ $from_ver>]::ffi::FFI_ArrowSchema::try_from(chunk.schema().field(col_num))?;
37                                    let (ffi_array, _) = [<arrow_crate_ $from_ver>]::ffi::to_ffi(&array)?;
38
39                                    // Convert ffi array from arrow-rs to this crate's version of ArrowArray
40                                    let ffi_array = unsafe { transmute::<[<arrow_crate_ $from_ver>]::ffi::FFI_ArrowArray, ArrowArray>(ffi_array) };
41
42                                    // Convert ffi schema from arrow-rs to this crate's version of ArrowSchema
43                                    let ffi_schema = unsafe { transmute::<[<arrow_crate_ $from_ver>]::ffi::FFI_ArrowSchema, ArrowSchema>(ffi_schema) };
44
45                                    ffi[col_num].1.push((ffi_array, ffi_schema));
46                                }
47                            }
48
49                            ffi
50                        }
51                    })
52                }
53            }
54        }
55    };
56}
57
58#[cfg(feature = "arrow_54")]
59arrow_to_ffi!("54");
60
61#[cfg(feature = "arrow_55")]
62arrow_to_ffi!("55");
63
64#[cfg(feature = "arrow_56")]
65arrow_to_ffi!("56");
66
67#[cfg(feature = "arrow_57")]
68arrow_to_ffi!("57");