polars_plan/dsl/
name.rs

1use polars_utils::format_pl_smallstr;
2#[cfg(feature = "dtype-struct")]
3use polars_utils::pl_str::PlSmallStr;
4
5use super::*;
6
7/// Specialized expressions for modifying the name of existing expressions.
8pub struct ExprNameNameSpace(pub(crate) Expr);
9
10impl ExprNameNameSpace {
11    /// Keep the original root name
12    ///
13    /// ```rust,no_run
14    /// # use polars_core::prelude::*;
15    /// # use polars_plan::prelude::*;
16    /// fn example(df: LazyFrame) -> LazyFrame {
17    ///     df.select([
18    /// // even thought the alias yields a different column name,
19    /// // `keep` will make sure that the original column name is used
20    ///         col("*").alias("foo").name().keep()
21    /// ])
22    /// }
23    /// ```
24    pub fn keep(self) -> Expr {
25        Expr::KeepName(Arc::new(self.0))
26    }
27
28    /// Define an alias by mapping a function over the original root column name.
29    pub fn map<F>(self, function: F) -> Expr
30    where
31        F: Fn(&PlSmallStr) -> PolarsResult<PlSmallStr> + 'static + Send + Sync,
32    {
33        let function = SpecialEq::new(Arc::new(function) as Arc<dyn RenameAliasFn>);
34        Expr::RenameAlias {
35            expr: Arc::new(self.0),
36            function,
37        }
38    }
39
40    /// Add a prefix to the root column name.
41    pub fn prefix(self, prefix: &str) -> Expr {
42        let prefix = prefix.to_string();
43        self.map(move |name| Ok(format_pl_smallstr!("{prefix}{name}")))
44    }
45
46    /// Add a suffix to the root column name.
47    pub fn suffix(self, suffix: &str) -> Expr {
48        let suffix = suffix.to_string();
49        self.map(move |name| Ok(format_pl_smallstr!("{name}{suffix}")))
50    }
51
52    /// Update the root column name to use lowercase characters.
53    #[allow(clippy::wrong_self_convention)]
54    pub fn to_lowercase(self) -> Expr {
55        self.map(move |name| Ok(PlSmallStr::from_string(name.to_lowercase())))
56    }
57
58    /// Update the root column name to use uppercase characters.
59    #[allow(clippy::wrong_self_convention)]
60    pub fn to_uppercase(self) -> Expr {
61        self.map(move |name| Ok(PlSmallStr::from_string(name.to_uppercase())))
62    }
63
64    #[cfg(feature = "dtype-struct")]
65    pub fn map_fields(self, function: FieldsNameMapper) -> Expr {
66        let f = function.clone();
67        self.0.map(
68            move |s| {
69                let s = s.struct_()?;
70                let fields = s
71                    .fields_as_series()
72                    .iter()
73                    .map(|fd| {
74                        let mut fd = fd.clone();
75                        fd.rename(function(fd.name()));
76                        fd
77                    })
78                    .collect::<Vec<_>>();
79                let mut out = StructChunked::from_series(s.name().clone(), s.len(), fields.iter())?;
80                out.zip_outer_validity(s);
81                Ok(Some(out.into_column()))
82            },
83            GetOutput::map_dtype(move |dt| match dt {
84                DataType::Struct(fds) => {
85                    let fields = fds
86                        .iter()
87                        .map(|fd| Field::new(f(fd.name()), fd.dtype().clone()))
88                        .collect();
89                    Ok(DataType::Struct(fields))
90                },
91                _ => panic!("Only struct dtype is supported for `map_fields`."),
92            }),
93        )
94    }
95
96    #[cfg(feature = "dtype-struct")]
97    pub fn prefix_fields(self, prefix: &str) -> Expr {
98        self.0
99            .map_private(FunctionExpr::StructExpr(StructFunction::PrefixFields(
100                PlSmallStr::from_str(prefix),
101            )))
102    }
103
104    #[cfg(feature = "dtype-struct")]
105    pub fn suffix_fields(self, suffix: &str) -> Expr {
106        self.0
107            .map_private(FunctionExpr::StructExpr(StructFunction::SuffixFields(
108                PlSmallStr::from_str(suffix),
109            )))
110    }
111}
112
113#[cfg(feature = "dtype-struct")]
114pub type FieldsNameMapper = Arc<dyn Fn(&str) -> PlSmallStr + Send + Sync>;