1#[cfg(feature = "dtype-struct")]
2use polars_utils::pl_str::PlSmallStr;
3
4use super::*;
5
6pub struct ExprNameNameSpace(pub(crate) Expr);
8
9impl ExprNameNameSpace {
10 pub fn keep(self) -> Expr {
24 Expr::KeepName(Arc::new(self.0))
25 }
26
27 pub fn map<F>(self, function: F) -> Expr
29 where
30 F: Fn(&PlSmallStr) -> PolarsResult<PlSmallStr> + 'static + Send + Sync,
31 {
32 let function = SpecialEq::new(Arc::new(function) as Arc<RenameAliasRustFn>);
33 Expr::RenameAlias {
34 expr: Arc::new(self.0),
35 function: RenameAliasFn::Rust(function),
36 }
37 }
38
39 #[cfg(feature = "python")]
41 pub fn map_udf(self, function: polars_utils::python_function::PythonObject) -> Expr {
42 Expr::RenameAlias {
43 expr: Arc::new(self.0),
44 function: RenameAliasFn::Python(SpecialEq::new(Arc::new(function))),
45 }
46 }
47
48 pub fn prefix(self, prefix: &str) -> Expr {
50 Expr::RenameAlias {
51 expr: Arc::new(self.0),
52 function: RenameAliasFn::Prefix(prefix.into()),
53 }
54 }
55
56 pub fn suffix(self, suffix: &str) -> Expr {
58 Expr::RenameAlias {
59 expr: Arc::new(self.0),
60 function: RenameAliasFn::Suffix(suffix.into()),
61 }
62 }
63
64 #[allow(clippy::wrong_self_convention)]
66 pub fn to_lowercase(self) -> Expr {
67 Expr::RenameAlias {
68 expr: Arc::new(self.0),
69 function: RenameAliasFn::ToLowercase,
70 }
71 }
72
73 #[allow(clippy::wrong_self_convention)]
75 pub fn to_uppercase(self) -> Expr {
76 Expr::RenameAlias {
77 expr: Arc::new(self.0),
78 function: RenameAliasFn::ToUppercase,
79 }
80 }
81
82 #[cfg(feature = "dtype-struct")]
83 pub fn map_fields(self, function: FieldsNameMapper) -> Expr {
84 let f = function.clone();
85 self.0.map(
86 move |s| {
87 let s = s.struct_()?;
88 let fields = s
89 .fields_as_series()
90 .iter()
91 .map(|fd| {
92 let mut fd = fd.clone();
93 fd.rename(function(fd.name()));
94 fd
95 })
96 .collect::<Vec<_>>();
97 let mut out = StructChunked::from_series(s.name().clone(), s.len(), fields.iter())?;
98 out.zip_outer_validity(s);
99 Ok(Some(out.into_column()))
100 },
101 GetOutput::map_dtype(move |dt| match dt {
102 DataType::Struct(fds) => {
103 let fields = fds
104 .iter()
105 .map(|fd| Field::new(f(fd.name()), fd.dtype().clone()))
106 .collect();
107 Ok(DataType::Struct(fields))
108 },
109 _ => panic!("Only struct dtype is supported for `map_fields`."),
110 }),
111 )
112 }
113
114 #[cfg(all(feature = "dtype-struct", feature = "python"))]
115 pub fn map_fields_udf(self, function: polars_utils::python_function::PythonObject) -> Expr {
116 self.0
117 .map_unary(FunctionExpr::StructExpr(StructFunction::MapFieldNames(
118 SpecialEq::new(Arc::new(function)),
119 )))
120 }
121
122 #[cfg(feature = "dtype-struct")]
123 pub fn prefix_fields(self, prefix: &str) -> Expr {
124 self.0
125 .map_unary(FunctionExpr::StructExpr(StructFunction::PrefixFields(
126 PlSmallStr::from_str(prefix),
127 )))
128 }
129
130 #[cfg(feature = "dtype-struct")]
131 pub fn suffix_fields(self, suffix: &str) -> Expr {
132 self.0
133 .map_unary(FunctionExpr::StructExpr(StructFunction::SuffixFields(
134 PlSmallStr::from_str(suffix),
135 )))
136 }
137}
138
139#[cfg(feature = "dtype-struct")]
140pub type FieldsNameMapper = Arc<dyn Fn(&str) -> PlSmallStr + Send + Sync>;