Skip to main content

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 columns = 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                        // Convert series to column
52                        let column = [<polars_crate_ $to_ver>]::frame::column::Column::from(
53                            [<polars_crate_ $to_ver>]::series::Series::from_arrow_chunks(
54                                name.into(),
55                                chunks,
56                            )?);
57
58                        // Put column in columns vec
59                        columns.push(column);
60
61
62                    }
63
64                    // Create DataFrame out of Vec of series
65                    Ok([<polars_crate_ $to_ver>]::frame::DataFrame::new_infer_height(columns)?)
66                }
67            }
68        }
69    };
70}
71
72#[cfg(feature = "polars_0_53")]
73ffi_to_polars!("0_53");
74
75macro_rules! ffi_to_polars {
76    ($to_ver:literal) => {
77        paste! {
78            impl Interchange {
79                #[doc = "Move Arrow data interchange format to Polars version `" $to_ver "`."]
80                pub fn [<to_polars_ $to_ver>](self) -> Result<[<polars_crate_ $to_ver>]::frame::DataFrame, InterchangeError> {
81
82                    // Prepare series vec
83                    let num_cols = self.ffi.len();
84                    let mut series = Vec::with_capacity(num_cols);
85
86                    // For columns in the ffi
87                    for s in self.ffi {
88
89                        // Prepare chunks vec
90                        let num_chunks = s.1.len();
91                        let mut chunks = Vec::with_capacity(num_chunks);
92
93                        // Get name of column
94                        let name = s.0;
95
96                        // For chunk in column
97                        for c in s.1 {
98
99                            // Convert ffi array from this crate's version of ArrowArray to polars-arrow
100                            let ffi_array = unsafe { transmute::<ArrowArray,  [<polars_arrow_ $to_ver>]::ffi::ArrowArray>(c.0) };
101
102                            // Convert ffi field from this crate's version of ArrowField to polars-arrow
103                            let ffi_field = unsafe { transmute::<ArrowSchema,  [<polars_arrow_ $to_ver>]::ffi::ArrowSchema>(c.1) };
104
105                            // Convert ffi to field
106                            let field = unsafe {
107                                [<polars_arrow_ $to_ver>]::ffi::import_field_from_c(&ffi_field)
108                            }?;
109
110                            // Convert ffi to chunk
111                            let array = unsafe {
112                                [<polars_arrow_ $to_ver>]::ffi::import_array_from_c(ffi_array, field.dtype().clone(),
113                                )
114                            }?;
115
116                            // Add the chunks to the vec of chunks
117                            chunks.push(array);
118                        }
119
120                        // Create series out of vec of chunks
121                        series.push(
122                            [<polars_crate_ $to_ver>]::series::Series::from_arrow_chunks(
123                                name.into(),
124                                chunks,
125                            )?,
126                        );
127                    }
128
129                    // Create DataFrame out of Vec of series
130                    Ok([<polars_crate_ $to_ver>]::frame::DataFrame::from_iter(series))
131                }
132            }
133        }
134    };
135}
136
137#[cfg(feature = "polars_0_43")]
138ffi_to_polars!("0_43");
139
140#[cfg(feature = "polars_0_44")]
141ffi_to_polars!("0_44");
142
143#[cfg(feature = "polars_0_45")]
144ffi_to_polars!("0_45");
145
146#[cfg(feature = "polars_0_46")]
147ffi_to_polars!("0_46");
148
149#[cfg(feature = "polars_0_47")]
150ffi_to_polars!("0_47");
151
152#[cfg(feature = "polars_0_48")]
153ffi_to_polars!("0_48");
154
155#[cfg(feature = "polars_0_49")]
156ffi_to_polars!("0_49");
157
158#[cfg(feature = "polars_0_50")]
159ffi_to_polars!("0_50");
160
161#[cfg(feature = "polars_0_51")]
162ffi_to_polars!("0_51");
163
164#[cfg(feature = "polars_0_52")]
165ffi_to_polars!("0_52");
166
167macro_rules! ffi_to_polars {
168    ($to_ver:literal) => {
169        paste! {
170            impl Interchange {
171                #[doc = "Move Arrow data interchange format to Polars version `" $to_ver "`."]
172                pub fn [<to_polars_ $to_ver>](self) -> Result<[<polars_crate_ $to_ver>]::frame::DataFrame, InterchangeError> {
173
174                    // Prepare series vec
175                    let num_cols = self.ffi.len();
176                    let mut series = Vec::with_capacity(num_cols);
177
178                    // For columns in the ffi
179                    for s in self.ffi {
180
181                        // Prepare chunks vec
182                        let num_chunks = s.1.len();
183                        let mut chunks = Vec::with_capacity(num_chunks);
184
185                        // Get name of column
186                        let name = s.0;
187
188                        // For chunk in column
189                        for c in s.1 {
190
191                            // Convert ffi array from this crate's version of ArrowArray to polars-arrow
192                            let ffi_array = unsafe { transmute::<ArrowArray,  [<polars_arrow_ $to_ver>]::ffi::ArrowArray>(c.0) };
193
194                            // Convert ffi field from this crate's version of ArrowField to polars-arrow
195                            let ffi_field = unsafe { transmute::<ArrowSchema,  [<polars_arrow_ $to_ver>]::ffi::ArrowSchema>(c.1) };
196
197                            // Convert ffi to field
198                            let field = unsafe {
199                                [<polars_arrow_ $to_ver>]::ffi::import_field_from_c(&ffi_field)
200                            }?;
201
202                            // Convert ffi to chunk
203                            let array = unsafe {
204                                [<polars_arrow_ $to_ver>]::ffi::import_array_from_c(ffi_array, field.data_type().clone(),
205                                )
206                            }?;
207
208                            // Add the chunks to the vec of chunks
209                            chunks.push(array);
210                        }
211
212                        // Create series out of vec of chunks
213                        series.push(
214                            [<polars_crate_ $to_ver>]::series::Series::from_arrow_chunks(
215                                &name,
216                                chunks,
217                            )?,
218                        );
219                    }
220
221                    // Create DataFrame out of Vec of series
222                    Ok([<polars_crate_ $to_ver>]::frame::DataFrame::from_iter(series))
223                }
224            }
225        }
226    };
227}
228
229#[cfg(feature = "polars_0_41")]
230ffi_to_polars!("0_41");
231
232#[cfg(feature = "polars_0_42")]
233ffi_to_polars!("0_42");
234
235macro_rules! ffi_to_polars {
236    ($to_ver:literal) => {
237        paste! {
238            impl Interchange {
239                #[doc = "Move Arrow data interchange format to Polars version `" $to_ver "`."]
240                pub fn [<to_polars_ $to_ver>](self) -> Result<[<polars_crate_ $to_ver>]::frame::DataFrame, InterchangeError> {
241
242                    // Prepare series vec
243                    let num_cols = self.ffi.len();
244                    let mut series = Vec::with_capacity(num_cols);
245
246                    // For columns in the ffi
247                    for s in self.ffi {
248
249                        // Prepare chunks vec
250                        let num_chunks = s.1.len();
251                        let mut chunks = Vec::with_capacity(num_chunks);
252
253                        // Get name of column
254                        let name = s.0;
255
256                        // For chunk in column
257                        for c in s.1 {
258
259                            // Convert ffi array from this crate's version of ArrowArray to polars-arrow
260                            let ffi_array = unsafe { transmute::<ArrowArray,  [<polars_arrow_ $to_ver>]::ffi::ArrowArray>(c.0) };
261
262                            // Convert ffi field from this crate's version of ArrowField to polars-arrow
263                            let ffi_field = unsafe { transmute::<ArrowSchema,  [<polars_arrow_ $to_ver>]::ffi::ArrowSchema>(c.1) };
264
265                            // Convert ffi to field
266                            let field = unsafe {
267                                [<polars_arrow_ $to_ver>]::ffi::import_field_from_c(&ffi_field)
268                            }?;
269
270                            // Convert ffi to chunk
271                            let array = unsafe {
272                                [<polars_arrow_ $to_ver>]::ffi::import_array_from_c(ffi_array, field.data_type().clone(),
273                                )
274                            }?;
275
276                            let series_chunk = [<polars_crate_ $to_ver>]::series::Series::from_arrow(
277                                &name,
278                                array,
279                            )?;
280
281                            // Add the chunks to the vec of chunks
282                            chunks.push(series_chunk);
283                        }
284
285                        // Create one series from multiple series chunks
286                        let mut chunk_iter = chunks.into_iter();
287                        let mut full_series = chunk_iter.next().unwrap();
288                        for c in chunk_iter {
289                            full_series.append(&c)?;
290                        }
291
292                        series.push(
293                            full_series,
294                        );
295                    }
296
297                    // Create DataFrame out of Vec of series
298                    Ok([<polars_crate_ $to_ver>]::frame::DataFrame::from_iter(series))
299                }
300            }
301        }
302    };
303}
304
305#[cfg(feature = "polars_0_40")]
306ffi_to_polars!("0_40");