I dislike the accepted answer for a couple of reasons
- It is type unsafe, and in fact you loose type information if you convert for example a
chrono::NaiveDate
field - it will come back as a str
in your DataFrame
.
- It is inefficient, since you need to serialize and deserialize your data.
I think a much better solution is a macro:
macro_rules! struct_to_dataframe {
($input:expr, [$($field:ident),+]) => {
{
let len = $input.len().to_owned();
// Extract the field values into separate vectors
$(let mut $field = Vec::with_capacity(len);)*
for e in $input.into_iter() {
$($field.push(e.$field);)*
}
df! {
$(stringify!($field) => $field,)*
}
}
};
}
You should be able to call it like so:
struct Test {
id:u32,
amount:u32
}
impl Test {
fn new(id:u32, amount:u32) -> Self{
Test{id,amount}
}
}
let test_vec:Vec<Test> = vec![Test::new(1,3), Test::new(3,4)];
let df = struct_to_dataframe!(test_vec, [id, amount]).unwrap();