df_interchange/from_polars.rs
1use paste::paste;
2use std::mem::transmute;
3
4use crate::{error::InterchangeError, ArrowArray, ArrowSchema, Interchange};
5
6macro_rules! polars_to_ffi {
7 ($from_ver:literal) => {
8 paste! {
9 impl Interchange {
10 #[doc = "Move Polars version `" $from_ver "` to the Arrow data interchange format."]
11 pub fn [<from_polars_ $from_ver>](df: [<polars_crate_ $from_ver>]::frame::DataFrame) -> Result<Self, InterchangeError> {
12 Ok(Self {
13 chunks_aligned: !df.should_rechunk(),
14 ffi: {
15 // Number of columns
16 let num_cols = df.width();
17
18 // Prepare ffi series vec
19 let mut ffi = Vec::with_capacity(num_cols);
20
21 // Get the columns from the df, as series
22 let series: Vec<[<polars_crate_ $from_ver>]::series::Series> = df
23 .into_columns()
24 .into_iter()
25 .map(|s| s.take_materialized_series())
26 .collect();
27
28 for s in series {
29 // Get arrow-type fields
30 let field = &s
31 .field()
32 .to_arrow([<polars_crate_ $from_ver>]::datatypes::CompatLevel::newest());
33
34 // Get name of column
35 let name = s.name().to_string();
36
37 // Get number of chunks in each column
38 let n_chunks = s.n_chunks();
39
40 // Prepare chunk vec
41 let mut ffi_chunk = Vec::with_capacity(num_cols);
42
43 for c in 0..n_chunks {
44
45 // Get ffi array
46 let ffi_array = [<polars_arrow_ $from_ver>]::ffi::export_array_to_c(
47 s.to_arrow(c, [<polars_crate_ $from_ver>]::datatypes::CompatLevel::newest()),
48 );
49
50 // Get ffi field
51 let ffi_field = [<polars_arrow_ $from_ver>]::ffi::export_field_to_c(field);
52
53 // Convert ffi array from polars-arrow to this crate's version of ArrowArray
54 let ffi_array = unsafe { transmute::<
55 [<polars_arrow_ $from_ver>]::ffi::ArrowArray,
56 ArrowArray,
57 >(ffi_array)};
58
59 // Convert ffi field from polars-arrow to this crate's version of ArrowField
60 let ffi_field = unsafe{transmute::<
61 [<polars_arrow_ $from_ver>]::ffi::ArrowSchema,
62 ArrowSchema,
63 >(ffi_field)};
64
65 // Create series
66 ffi_chunk.push((ffi_array, ffi_field));
67 }
68
69 ffi.push((name, ffi_chunk));
70 }
71
72 ffi
73 }
74 })
75 }
76 }
77 }
78 };
79}
80
81#[cfg(feature = "polars_0_53")]
82polars_to_ffi!("0_53");
83
84macro_rules! polars_to_ffi {
85 ($from_ver:literal) => {
86 paste! {
87 impl Interchange {
88 #[doc = "Move Polars version `" $from_ver "` to the Arrow data interchange format."]
89 pub fn [<from_polars_ $from_ver>](df: [<polars_crate_ $from_ver>]::frame::DataFrame) -> Result<Self, InterchangeError> {
90 Ok(Self {
91 chunks_aligned: !df.should_rechunk(),
92 ffi: {
93 // Number of columns
94 let num_cols = df.width();
95
96 // Prepare ffi series vec
97 let mut ffi = Vec::with_capacity(num_cols);
98
99 // Get the columns from the df, as series
100 let series: Vec<[<polars_crate_ $from_ver>]::series::Series> = df
101 .take_columns()
102 .into_iter()
103 .map(|s| s.take_materialized_series())
104 .collect();
105
106 for s in series {
107 // Get arrow-type fields
108 let field = &s
109 .field()
110 .to_arrow([<polars_crate_ $from_ver>]::datatypes::CompatLevel::newest());
111
112 // Get name of column
113 let name = s.name().to_string();
114
115 // Get number of chunks in each column
116 let n_chunks = s.n_chunks();
117
118 // Prepare chunk vec
119 let mut ffi_chunk = Vec::with_capacity(num_cols);
120
121 for c in 0..n_chunks {
122
123 // Get ffi array
124 let ffi_array = [<polars_arrow_ $from_ver>]::ffi::export_array_to_c(
125 s.to_arrow(c, [<polars_crate_ $from_ver>]::datatypes::CompatLevel::newest()),
126 );
127
128 // Get ffi field
129 let ffi_field = [<polars_arrow_ $from_ver>]::ffi::export_field_to_c(field);
130
131 // Convert ffi array from polars-arrow to this crate's version of ArrowArray
132 let ffi_array = unsafe { transmute::<
133 [<polars_arrow_ $from_ver>]::ffi::ArrowArray,
134 ArrowArray,
135 >(ffi_array)};
136
137 // Convert ffi field from polars-arrow to this crate's version of ArrowField
138 let ffi_field = unsafe{transmute::<
139 [<polars_arrow_ $from_ver>]::ffi::ArrowSchema,
140 ArrowSchema,
141 >(ffi_field)};
142
143 // Create series
144 ffi_chunk.push((ffi_array, ffi_field));
145 }
146
147 ffi.push((name, ffi_chunk));
148 }
149
150 ffi
151 }
152 })
153 }
154 }
155 }
156 };
157}
158#[cfg(feature = "polars_0_44")]
159polars_to_ffi!("0_44");
160
161#[cfg(feature = "polars_0_45")]
162polars_to_ffi!("0_45");
163
164#[cfg(feature = "polars_0_46")]
165polars_to_ffi!("0_46");
166
167#[cfg(feature = "polars_0_47")]
168polars_to_ffi!("0_47");
169
170#[cfg(feature = "polars_0_48")]
171polars_to_ffi!("0_48");
172
173#[cfg(feature = "polars_0_49")]
174polars_to_ffi!("0_49");
175
176#[cfg(feature = "polars_0_50")]
177polars_to_ffi!("0_50");
178
179#[cfg(feature = "polars_0_51")]
180polars_to_ffi!("0_51");
181
182#[cfg(feature = "polars_0_52")]
183polars_to_ffi!("0_52");
184
185macro_rules! polars_to_ffi {
186 ($from_ver:literal) => {
187 paste! {
188 impl Interchange {
189 #[doc = "Move Polars version `" $from_ver "` to the Arrow data interchange format."]
190 pub fn [<from_polars_ $from_ver>](df: [<polars_crate_ $from_ver>]::frame::DataFrame) -> Result<Self, InterchangeError> {
191 Ok(Self {
192 chunks_aligned: !df.should_rechunk(),
193 ffi: {
194 // Number of columns
195 let num_cols = df.width();
196
197 // Prepare ffi series vec
198 let mut ffi = Vec::with_capacity(num_cols);
199
200 // Get the series from the df
201 let series: Vec<[<polars_crate_ $from_ver>]::series::Series> = df.take_columns();
202
203 for s in series {
204 // Get arrow-type fields
205 let field = &s
206 .field()
207 .to_arrow([<polars_crate_ $from_ver>]::datatypes::CompatLevel::newest());
208
209 // Get name of column
210 let name = s.name().to_string();
211
212 // Get number of chunks in each column
213 let n_chunks = s.n_chunks();
214
215 // Prepare chunk vec
216 let mut ffi_chunk = Vec::with_capacity(num_cols);
217
218 for c in 0..n_chunks {
219
220 // Get ffi array
221 let ffi_array = [<polars_arrow_ $from_ver>]::ffi::export_array_to_c(
222 s.to_arrow(c, [<polars_crate_ $from_ver>]::datatypes::CompatLevel::newest()),
223 );
224
225 // Get ffi field
226 let ffi_field = [<polars_arrow_ $from_ver>]::ffi::export_field_to_c(field);
227
228 // Convert ffi array from polars-arrow to this crate's version of ArrowArray
229 let ffi_array = unsafe { transmute::<
230 [<polars_arrow_ $from_ver>]::ffi::ArrowArray,
231 ArrowArray,
232 >(ffi_array)};
233
234 // Convert ffi field from polars-arrow to this crate's version of ArrowField
235 let ffi_field = unsafe{transmute::<
236 [<polars_arrow_ $from_ver>]::ffi::ArrowSchema,
237 ArrowSchema,
238 >(ffi_field)};
239
240 // Create series
241 ffi_chunk.push((ffi_array, ffi_field));
242 }
243
244 ffi.push((name, ffi_chunk));
245 }
246
247 ffi
248 }
249 })
250 }
251 }
252 }
253 };
254}
255
256#[cfg(feature = "polars_0_42")]
257polars_to_ffi!("0_42");
258
259#[cfg(feature = "polars_0_43")]
260polars_to_ffi!("0_43");
261
262macro_rules! polars_to_ffi {
263 ($from_ver:literal) => {
264 paste! {
265 impl Interchange {
266 #[doc = "Move Polars version `" $from_ver "` to the Arrow data interchange format."]
267 pub fn [<from_polars_ $from_ver>](df: [<polars_crate_ $from_ver>]::frame::DataFrame) -> Result<Self, InterchangeError> {
268 Ok(Self {
269 chunks_aligned: !df.should_rechunk(),
270 ffi: {
271 // Number of columns
272 let num_cols = df.width();
273
274 // Prepare ffi series vec
275 let mut ffi = Vec::with_capacity(num_cols);
276
277 // Get column names to remove them one by one
278 let names = df.get_column_names();
279
280 // Get the series from the df
281 let series: Vec<[<polars_crate_ $from_ver>]::series::Series> = df.select_series(names)?;
282
283 for s in series {
284 // Get arrow-type fields
285 let field = &s
286 .field()
287 .to_arrow(false);
288
289 // Get name of column
290 let name = s.name().to_string();
291
292 // Get number of chunks in each column
293 let n_chunks = s.n_chunks();
294
295 // Prepare chunk vec
296 let mut ffi_chunk = Vec::with_capacity(num_cols);
297
298 for c in 0..n_chunks {
299
300 // Get ffi array
301 let ffi_array = [<polars_arrow_ $from_ver>]::ffi::export_array_to_c(
302 s.to_arrow(c, false),
303 );
304
305 // Get ffi field
306 let ffi_field = [<polars_arrow_ $from_ver>]::ffi::export_field_to_c(field);
307
308 // Convert ffi array from polars-arrow to this crate's version of ArrowArray
309 let ffi_array = unsafe { transmute::<
310 [<polars_arrow_ $from_ver>]::ffi::ArrowArray,
311 ArrowArray,
312 >(ffi_array)};
313
314 // Convert ffi field from polars-arrow to this crate's version of ArrowField
315 let ffi_field = unsafe{transmute::<
316 [<polars_arrow_ $from_ver>]::ffi::ArrowSchema,
317 ArrowSchema,
318 >(ffi_field)};
319
320 // Create series
321 ffi_chunk.push((ffi_array, ffi_field));
322 }
323
324 ffi.push((name, ffi_chunk));
325 }
326
327 ffi
328 }
329 })
330 }
331 }
332 }
333 };
334}
335
336#[cfg(feature = "polars_0_40")]
337polars_to_ffi!("0_40");
338
339#[cfg(feature = "polars_0_41")]
340polars_to_ffi!("0_41");