Skip to main content

df_derive/
lib.rs

1//! User-facing facade for deriving Polars `DataFrame` conversions.
2//!
3//! Most users should depend on this crate, import the prelude, and derive
4//! `ToDataFrame` without any runtime-path attributes:
5//!
6//! ```toml
7//! [dependencies]
8//! df-derive = "0.3"
9//! polars = "0.53"
10//! ```
11//!
12//! The default facade hides the macro's `polars-arrow` implementation
13//! dependency behind `df_derive::dataframe`; custom runtimes still need to
14//! provide their own compatible direct dependencies.
15//!
16//! ```ignore
17//! use df_derive::prelude::*;
18//!
19//! #[derive(ToDataFrame)]
20//! struct Trade {
21//!     symbol: String,
22//!     price: f64,
23//!     size: u64,
24//! }
25//! ```
26//!
27//! The derive macro targets [`dataframe`] by default, which is re-exported
28//! from `df-derive-core`. Power users can depend on `df-derive-macros`
29//! directly or use `#[df_derive(trait = "...")]`,
30//! `#[df_derive(columnar = "...")]`, and
31//! `#[df_derive(decimal128_encode = "...")]` to target a custom runtime.
32//! Explicit paths back to `df_derive::dataframe::ToDataFrame` or
33//! `df_derive_core::dataframe::ToDataFrame` still use the default runtime's
34//! hidden dependency re-exports.
35
36// `polars` pulls a wide transitive dependency tree where multiple resolved
37// versions are unavoidable. `clippy::multiple_crate_versions` is part of the
38// `clippy::cargo` group `just lint` enables; allow it here so linting stays
39// focused on this crate's own code.
40#![allow(clippy::multiple_crate_versions)]
41
42pub use df_derive_core::dataframe;
43pub use df_derive_macros::ToDataFrame;
44
45/// Common imports for normal users.
46///
47/// This includes the derive macro and the runtime traits. The trait
48/// `ToDataFrame` is also exported as `ToDataFrameTrait` for code that wants
49/// an unambiguous type-namespace name.
50pub mod prelude {
51    pub use crate::ToDataFrame;
52    pub use crate::dataframe::{
53        Columnar, Decimal128Encode, ToDataFrame, ToDataFrame as ToDataFrameTrait, ToDataFrameVec,
54    };
55}
56
57#[cfg(test)]
58mod tests {
59    use crate::ToDataFrame;
60
61    #[derive(ToDataFrame)]
62    struct SelfCrateRow {
63        id: u32,
64        label: String,
65    }
66
67    #[test]
68    fn derive_uses_facade_runtime_inside_facade_crate() -> polars::prelude::PolarsResult<()> {
69        use crate::dataframe::{ToDataFrame as _, ToDataFrameVec as _};
70
71        let row = SelfCrateRow {
72            id: 1,
73            label: "facade".to_owned(),
74        };
75        let single = row.to_dataframe()?;
76        assert_eq!(single.shape(), (1, 2));
77
78        let rows = [
79            row,
80            SelfCrateRow {
81                id: 2,
82                label: "self".to_owned(),
83            },
84        ];
85        let batch = rows.as_slice().to_dataframe()?;
86        assert_eq!(batch.shape(), (2, 2));
87
88        Ok(())
89    }
90}