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
83macro_rules! ffi_to_polars {
84    ($to_ver:literal) => {
85        paste! {
86            impl Interchange {
87                #[doc = "Move Arrow data interchange format to Polars version `" $to_ver "`."]
88                pub fn [<to_polars_ $to_ver>](self) -> Result<[<polars_crate_ $to_ver>]::frame::DataFrame, InterchangeError> {
89
90                    // Prepare series vec
91                    let num_cols = self.ffi.len();
92                    let mut series = Vec::with_capacity(num_cols);
93
94                    // For columns in the ffi
95                    for s in self.ffi {
96
97                        // Prepare chunks vec
98                        let num_chunks = s.1.len();
99                        let mut chunks = Vec::with_capacity(num_chunks);
100
101                        // Get name of column
102                        let name = s.0;
103
104                        // For chunk in column
105                        for c in s.1 {
106
107                            // Convert ffi array from this crate's version of ArrowArray to polars-arrow
108                            let ffi_array = unsafe { transmute::<ArrowArray,  [<polars_arrow_ $to_ver>]::ffi::ArrowArray>(c.0) };
109
110                            // Convert ffi field from this crate's version of ArrowField to polars-arrow
111                            let ffi_field = unsafe { transmute::<ArrowSchema,  [<polars_arrow_ $to_ver>]::ffi::ArrowSchema>(c.1) };
112
113                            // Convert ffi to field
114                            let field = unsafe {
115                                [<polars_arrow_ $to_ver>]::ffi::import_field_from_c(&ffi_field)
116                            }?;
117
118                            // Convert ffi to chunk
119                            let array = unsafe {
120                                [<polars_arrow_ $to_ver>]::ffi::import_array_from_c(ffi_array, field.data_type().clone(),
121                                )
122                            }?;
123
124                            // Add the chunks to the vec of chunks
125                            chunks.push(array);
126                        }
127
128                        // Create series out of vec of chunks
129                        series.push(
130                            [<polars_crate_ $to_ver>]::series::Series::from_arrow_chunks(
131                                &name,
132                                chunks,
133                            )?,
134                        );
135                    }
136
137                    // Create DataFrame out of Vec of series
138                    Ok([<polars_crate_ $to_ver>]::frame::DataFrame::from_iter(series))
139                }
140            }
141        }
142    };
143}
144
145#[cfg(feature = "polars_0_41")]
146ffi_to_polars!("0_41");
147
148#[cfg(feature = "polars_0_42")]
149ffi_to_polars!("0_42");
150
151macro_rules! ffi_to_polars {
152    ($to_ver:literal) => {
153        paste! {
154            impl Interchange {
155                #[doc = "Move Arrow data interchange format to Polars version `" $to_ver "`."]
156                pub fn [<to_polars_ $to_ver>](self) -> Result<[<polars_crate_ $to_ver>]::frame::DataFrame, InterchangeError> {
157
158                    // Prepare series vec
159                    let num_cols = self.ffi.len();
160                    let mut series = Vec::with_capacity(num_cols);
161
162                    // For columns in the ffi
163                    for s in self.ffi {
164
165                        // Prepare chunks vec
166                        let num_chunks = s.1.len();
167                        let mut chunks = Vec::with_capacity(num_chunks);
168
169                        // Get name of column
170                        let name = s.0;
171
172                        // For chunk in column
173                        for c in s.1 {
174
175                            // Convert ffi array from this crate's version of ArrowArray to polars-arrow
176                            let ffi_array = unsafe { transmute::<ArrowArray,  [<polars_arrow_ $to_ver>]::ffi::ArrowArray>(c.0) };
177
178                            // Convert ffi field from this crate's version of ArrowField to polars-arrow
179                            let ffi_field = unsafe { transmute::<ArrowSchema,  [<polars_arrow_ $to_ver>]::ffi::ArrowSchema>(c.1) };
180
181                            // Convert ffi to field
182                            let field = unsafe {
183                                [<polars_arrow_ $to_ver>]::ffi::import_field_from_c(&ffi_field)
184                            }?;
185
186                            // Convert ffi to chunk
187                            let array = unsafe {
188                                [<polars_arrow_ $to_ver>]::ffi::import_array_from_c(ffi_array, field.data_type().clone(),
189                                )
190                            }?;
191
192                            let series_chunk = [<polars_crate_ $to_ver>]::series::Series::from_arrow(
193                                &name,
194                                array,
195                            )?;
196
197                            // Add the chunks to the vec of chunks
198                            chunks.push(series_chunk);
199                        }
200
201                        // Create one series from multiple series chunks
202                        let mut chunk_iter = chunks.into_iter();
203                        let mut full_series = chunk_iter.next().unwrap();
204                        for c in chunk_iter {
205                            full_series.append(&c)?;
206                        }
207
208                        series.push(
209                            full_series,
210                        );
211                    }
212
213                    // Create DataFrame out of Vec of series
214                    Ok([<polars_crate_ $to_ver>]::frame::DataFrame::from_iter(series))
215                }
216            }
217        }
218    };
219}
220
221#[cfg(feature = "polars_0_40")]
222ffi_to_polars!("0_40");