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