df_interchange/
to_polars.rs

1use paste::paste;
2use std::mem::transmute;
3
4use crate::{error::InterchangeError, ArrowArray, ArrowSchema, Interchange};
5
6macro_rules! ffi_to_polars {
7    ($to_ver:literal) => {
8        paste! {
9            impl Interchange {
10                #[doc = "Move Arrow data interchange format to Polars version `" $to_ver "`."]
11                pub fn [<to_polars_ $to_ver>](self) -> Result<[<polars_crate_ $to_ver>]::frame::DataFrame, InterchangeError> {
12
13                    // Prepare series vec
14                    let num_cols = self.ffi.len();
15                    let mut series = Vec::with_capacity(num_cols);
16
17                    // For columns in the ffi
18                    for s in self.ffi {
19
20                        // Prepare chunks vec
21                        let num_chunks = s.1.len();
22                        let mut chunks = Vec::with_capacity(num_chunks);
23
24                        // Get name of column
25                        let name = s.0;
26
27                        // For chunk in column
28                        for c in s.1 {
29
30                            // Convert ffi array from this crate's version of ArrowArray to polars-arrow
31                            let ffi_array = unsafe { transmute::<ArrowArray,  [<polars_arrow_ $to_ver>]::ffi::ArrowArray>(c.0) };
32
33                            // Convert ffi field from this crate's version of ArrowField to polars-arrow
34                            let ffi_field = unsafe { transmute::<ArrowSchema,  [<polars_arrow_ $to_ver>]::ffi::ArrowSchema>(c.1) };
35
36                            // Convert ffi to field
37                            let field = unsafe {
38                                [<polars_arrow_ $to_ver>]::ffi::import_field_from_c(&ffi_field)
39                            }?;
40
41                            // Convert ffi to chunk
42                            let array = unsafe {
43                                [<polars_arrow_ $to_ver>]::ffi::import_array_from_c(ffi_array, field.dtype().clone(),
44                                )
45                            }?;
46
47                            // Add the chunks to the vec of chunks
48                            chunks.push(array);
49                        }
50
51                        // Create series out of vec of chunks
52                        series.push(
53                            [<polars_crate_ $to_ver>]::series::Series::from_arrow_chunks(
54                                name.into(),
55                                chunks,
56                            )?,
57                        );
58                    }
59
60                    // Create DataFrame out of Vec of series
61                    Ok([<polars_crate_ $to_ver>]::frame::DataFrame::from_iter(series))
62                }
63            }
64        }
65    };
66}
67
68#[cfg(feature = "polars_0_43")]
69ffi_to_polars!("0_43");
70
71#[cfg(feature = "polars_0_44")]
72ffi_to_polars!("0_44");
73
74#[cfg(feature = "polars_0_45")]
75ffi_to_polars!("0_45");
76
77#[cfg(feature = "polars_0_46")]
78ffi_to_polars!("0_46");
79
80#[cfg(feature = "polars_0_47")]
81ffi_to_polars!("0_47");
82
83#[cfg(feature = "polars_0_48")]
84ffi_to_polars!("0_48");
85
86#[cfg(feature = "polars_0_49")]
87ffi_to_polars!("0_49");
88
89#[cfg(feature = "polars_0_50")]
90ffi_to_polars!("0_50");
91
92#[cfg(feature = "polars_0_51")]
93ffi_to_polars!("0_51");
94
95#[cfg(feature = "polars_0_52")]
96ffi_to_polars!("0_52");
97
98macro_rules! ffi_to_polars {
99    ($to_ver:literal) => {
100        paste! {
101            impl Interchange {
102                #[doc = "Move Arrow data interchange format to Polars version `" $to_ver "`."]
103                pub fn [<to_polars_ $to_ver>](self) -> Result<[<polars_crate_ $to_ver>]::frame::DataFrame, InterchangeError> {
104
105                    // Prepare series vec
106                    let num_cols = self.ffi.len();
107                    let mut series = Vec::with_capacity(num_cols);
108
109                    // For columns in the ffi
110                    for s in self.ffi {
111
112                        // Prepare chunks vec
113                        let num_chunks = s.1.len();
114                        let mut chunks = Vec::with_capacity(num_chunks);
115
116                        // Get name of column
117                        let name = s.0;
118
119                        // For chunk in column
120                        for c in s.1 {
121
122                            // Convert ffi array from this crate's version of ArrowArray to polars-arrow
123                            let ffi_array = unsafe { transmute::<ArrowArray,  [<polars_arrow_ $to_ver>]::ffi::ArrowArray>(c.0) };
124
125                            // Convert ffi field from this crate's version of ArrowField to polars-arrow
126                            let ffi_field = unsafe { transmute::<ArrowSchema,  [<polars_arrow_ $to_ver>]::ffi::ArrowSchema>(c.1) };
127
128                            // Convert ffi to field
129                            let field = unsafe {
130                                [<polars_arrow_ $to_ver>]::ffi::import_field_from_c(&ffi_field)
131                            }?;
132
133                            // Convert ffi to chunk
134                            let array = unsafe {
135                                [<polars_arrow_ $to_ver>]::ffi::import_array_from_c(ffi_array, field.data_type().clone(),
136                                )
137                            }?;
138
139                            // Add the chunks to the vec of chunks
140                            chunks.push(array);
141                        }
142
143                        // Create series out of vec of chunks
144                        series.push(
145                            [<polars_crate_ $to_ver>]::series::Series::from_arrow_chunks(
146                                &name,
147                                chunks,
148                            )?,
149                        );
150                    }
151
152                    // Create DataFrame out of Vec of series
153                    Ok([<polars_crate_ $to_ver>]::frame::DataFrame::from_iter(series))
154                }
155            }
156        }
157    };
158}
159
160#[cfg(feature = "polars_0_41")]
161ffi_to_polars!("0_41");
162
163#[cfg(feature = "polars_0_42")]
164ffi_to_polars!("0_42");
165
166macro_rules! ffi_to_polars {
167    ($to_ver:literal) => {
168        paste! {
169            impl Interchange {
170                #[doc = "Move Arrow data interchange format to Polars version `" $to_ver "`."]
171                pub fn [<to_polars_ $to_ver>](self) -> Result<[<polars_crate_ $to_ver>]::frame::DataFrame, InterchangeError> {
172
173                    // Prepare series vec
174                    let num_cols = self.ffi.len();
175                    let mut series = Vec::with_capacity(num_cols);
176
177                    // For columns in the ffi
178                    for s in self.ffi {
179
180                        // Prepare chunks vec
181                        let num_chunks = s.1.len();
182                        let mut chunks = Vec::with_capacity(num_chunks);
183
184                        // Get name of column
185                        let name = s.0;
186
187                        // For chunk in column
188                        for c in s.1 {
189
190                            // Convert ffi array from this crate's version of ArrowArray to polars-arrow
191                            let ffi_array = unsafe { transmute::<ArrowArray,  [<polars_arrow_ $to_ver>]::ffi::ArrowArray>(c.0) };
192
193                            // Convert ffi field from this crate's version of ArrowField to polars-arrow
194                            let ffi_field = unsafe { transmute::<ArrowSchema,  [<polars_arrow_ $to_ver>]::ffi::ArrowSchema>(c.1) };
195
196                            // Convert ffi to field
197                            let field = unsafe {
198                                [<polars_arrow_ $to_ver>]::ffi::import_field_from_c(&ffi_field)
199                            }?;
200
201                            // Convert ffi to chunk
202                            let array = unsafe {
203                                [<polars_arrow_ $to_ver>]::ffi::import_array_from_c(ffi_array, field.data_type().clone(),
204                                )
205                            }?;
206
207                            let series_chunk = [<polars_crate_ $to_ver>]::series::Series::from_arrow(
208                                &name,
209                                array,
210                            )?;
211
212                            // Add the chunks to the vec of chunks
213                            chunks.push(series_chunk);
214                        }
215
216                        // Create one series from multiple series chunks
217                        let mut chunk_iter = chunks.into_iter();
218                        let mut full_series = chunk_iter.next().unwrap();
219                        for c in chunk_iter {
220                            full_series.append(&c)?;
221                        }
222
223                        series.push(
224                            full_series,
225                        );
226                    }
227
228                    // Create DataFrame out of Vec of series
229                    Ok([<polars_crate_ $to_ver>]::frame::DataFrame::from_iter(series))
230                }
231            }
232        }
233    };
234}
235
236#[cfg(feature = "polars_0_40")]
237ffi_to_polars!("0_40");