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