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");