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 .take_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#[cfg(feature = "polars_0_44")]
81polars_to_ffi!("0_44");
82
83#[cfg(feature = "polars_0_45")]
84polars_to_ffi!("0_45");
85
86#[cfg(feature = "polars_0_46")]
87polars_to_ffi!("0_46");
88
89#[cfg(feature = "polars_0_47")]
90polars_to_ffi!("0_47");
91
92#[cfg(feature = "polars_0_48")]
93polars_to_ffi!("0_48");
94
95#[cfg(feature = "polars_0_49")]
96polars_to_ffi!("0_49");
97
98#[cfg(feature = "polars_0_50")]
99polars_to_ffi!("0_50");
100
101#[cfg(feature = "polars_0_51")]
102polars_to_ffi!("0_51");
103
104#[cfg(feature = "polars_0_52")]
105polars_to_ffi!("0_52");
106
107macro_rules! polars_to_ffi {
108 ($from_ver:literal) => {
109 paste! {
110 impl Interchange {
111 #[doc = "Move Polars version `" $from_ver "` to the Arrow data interchange format."]
112 pub fn [<from_polars_ $from_ver>](df: [<polars_crate_ $from_ver>]::frame::DataFrame) -> Result<Self, InterchangeError> {
113 Ok(Self {
114 chunks_aligned: !df.should_rechunk(),
115 ffi: {
116 // Number of columns
117 let num_cols = df.width();
118
119 // Prepare ffi series vec
120 let mut ffi = Vec::with_capacity(num_cols);
121
122 // Get the series from the df
123 let series: Vec<[<polars_crate_ $from_ver>]::series::Series> = df.take_columns();
124
125 for s in series {
126 // Get arrow-type fields
127 let field = &s
128 .field()
129 .to_arrow([<polars_crate_ $from_ver>]::datatypes::CompatLevel::newest());
130
131 // Get name of column
132 let name = s.name().to_string();
133
134 // Get number of chunks in each column
135 let n_chunks = s.n_chunks();
136
137 // Prepare chunk vec
138 let mut ffi_chunk = Vec::with_capacity(num_cols);
139
140 for c in 0..n_chunks {
141
142 // Get ffi array
143 let ffi_array = [<polars_arrow_ $from_ver>]::ffi::export_array_to_c(
144 s.to_arrow(c, [<polars_crate_ $from_ver>]::datatypes::CompatLevel::newest()),
145 );
146
147 // Get ffi field
148 let ffi_field = [<polars_arrow_ $from_ver>]::ffi::export_field_to_c(field);
149
150 // Convert ffi array from polars-arrow to this crate's version of ArrowArray
151 let ffi_array = unsafe { transmute::<
152 [<polars_arrow_ $from_ver>]::ffi::ArrowArray,
153 ArrowArray,
154 >(ffi_array)};
155
156 // Convert ffi field from polars-arrow to this crate's version of ArrowField
157 let ffi_field = unsafe{transmute::<
158 [<polars_arrow_ $from_ver>]::ffi::ArrowSchema,
159 ArrowSchema,
160 >(ffi_field)};
161
162 // Create series
163 ffi_chunk.push((ffi_array, ffi_field));
164 }
165
166 ffi.push((name, ffi_chunk));
167 }
168
169 ffi
170 }
171 })
172 }
173 }
174 }
175 };
176}
177
178#[cfg(feature = "polars_0_42")]
179polars_to_ffi!("0_42");
180
181#[cfg(feature = "polars_0_43")]
182polars_to_ffi!("0_43");
183
184macro_rules! polars_to_ffi {
185 ($from_ver:literal) => {
186 paste! {
187 impl Interchange {
188 #[doc = "Move Polars version `" $from_ver "` to the Arrow data interchange format."]
189 pub fn [<from_polars_ $from_ver>](df: [<polars_crate_ $from_ver>]::frame::DataFrame) -> Result<Self, InterchangeError> {
190 Ok(Self {
191 chunks_aligned: !df.should_rechunk(),
192 ffi: {
193 // Number of columns
194 let num_cols = df.width();
195
196 // Prepare ffi series vec
197 let mut ffi = Vec::with_capacity(num_cols);
198
199 // Get column names to remove them one by one
200 let names = df.get_column_names();
201
202 // Get the series from the df
203 let series: Vec<[<polars_crate_ $from_ver>]::series::Series> = df.select_series(names)?;
204
205 for s in series {
206 // Get arrow-type fields
207 let field = &s
208 .field()
209 .to_arrow(false);
210
211 // Get name of column
212 let name = s.name().to_string();
213
214 // Get number of chunks in each column
215 let n_chunks = s.n_chunks();
216
217 // Prepare chunk vec
218 let mut ffi_chunk = Vec::with_capacity(num_cols);
219
220 for c in 0..n_chunks {
221
222 // Get ffi array
223 let ffi_array = [<polars_arrow_ $from_ver>]::ffi::export_array_to_c(
224 s.to_arrow(c, false),
225 );
226
227 // Get ffi field
228 let ffi_field = [<polars_arrow_ $from_ver>]::ffi::export_field_to_c(field);
229
230 // Convert ffi array from polars-arrow to this crate's version of ArrowArray
231 let ffi_array = unsafe { transmute::<
232 [<polars_arrow_ $from_ver>]::ffi::ArrowArray,
233 ArrowArray,
234 >(ffi_array)};
235
236 // Convert ffi field from polars-arrow to this crate's version of ArrowField
237 let ffi_field = unsafe{transmute::<
238 [<polars_arrow_ $from_ver>]::ffi::ArrowSchema,
239 ArrowSchema,
240 >(ffi_field)};
241
242 // Create series
243 ffi_chunk.push((ffi_array, ffi_field));
244 }
245
246 ffi.push((name, ffi_chunk));
247 }
248
249 ffi
250 }
251 })
252 }
253 }
254 }
255 };
256}
257
258#[cfg(feature = "polars_0_40")]
259polars_to_ffi!("0_40");
260
261#[cfg(feature = "polars_0_41")]
262polars_to_ffi!("0_41");