1use crate::Pipe;
58use crate::case;
59
60pub struct Upper;
64
65impl Pipe for Upper {
66 type Input = String;
67 type Output = proc_macro2::Ident;
68
69 fn pipe(&self, input: String) -> proc_macro2::Ident {
70 proc_macro2::Ident::new(&input.to_uppercase(), proc_macro2::Span::call_site())
71 }
72}
73
74pub struct Lower;
78
79impl Pipe for Lower {
80 type Input = String;
81 type Output = proc_macro2::Ident;
82
83 fn pipe(&self, input: String) -> proc_macro2::Ident {
84 proc_macro2::Ident::new(&input.to_lowercase(), proc_macro2::Span::call_site())
85 }
86}
87
88pub struct Snake;
92
93impl Pipe for Snake {
94 type Input = String;
95 type Output = proc_macro2::Ident;
96
97 fn pipe(&self, input: String) -> proc_macro2::Ident {
98 proc_macro2::Ident::new(&case::to_snake(&input), proc_macro2::Span::call_site())
99 }
100}
101
102pub struct Camel;
106
107impl Pipe for Camel {
108 type Input = String;
109 type Output = proc_macro2::Ident;
110
111 fn pipe(&self, input: String) -> proc_macro2::Ident {
112 proc_macro2::Ident::new(&case::to_camel(&input), proc_macro2::Span::call_site())
113 }
114}
115
116pub struct Pascal;
120
121impl Pipe for Pascal {
122 type Input = String;
123 type Output = proc_macro2::Ident;
124
125 fn pipe(&self, input: String) -> proc_macro2::Ident {
126 proc_macro2::Ident::new(&case::to_pascal(&input), proc_macro2::Span::call_site())
127 }
128}
129
130pub struct Kebab;
137
138impl Pipe for Kebab {
139 type Input = String;
140 type Output = syn::LitStr;
141
142 fn pipe(&self, input: String) -> syn::LitStr {
143 syn::LitStr::new(&case::to_kebab(&input), proc_macro2::Span::call_site())
144 }
145}
146
147pub struct Screaming;
151
152impl Pipe for Screaming {
153 type Input = String;
154 type Output = proc_macro2::Ident;
155
156 fn pipe(&self, input: String) -> proc_macro2::Ident {
157 proc_macro2::Ident::new(&case::to_screaming(&input), proc_macro2::Span::call_site())
158 }
159}
160
161pub struct Ident(pub &'static str);
167
168impl Pipe for Ident {
169 type Input = String;
170 type Output = proc_macro2::Ident;
171
172 fn pipe(&self, input: String) -> proc_macro2::Ident {
173 let formatted = self.0.replace("{}", &input);
174 proc_macro2::Ident::new(&formatted, proc_macro2::Span::call_site())
175 }
176}
177
178pub struct Fmt(pub &'static str);
184
185impl Pipe for Fmt {
186 type Input = String;
187 type Output = syn::LitStr;
188
189 fn pipe(&self, input: String) -> syn::LitStr {
190 let formatted = self.0.replace("{}", &input);
191 syn::LitStr::new(&formatted, proc_macro2::Span::call_site())
192 }
193}
194
195pub struct Str;
199
200impl Pipe for Str {
201 type Input = String;
202 type Output = syn::LitStr;
203
204 fn pipe(&self, input: String) -> syn::LitStr {
205 syn::LitStr::new(&input, proc_macro2::Span::call_site())
206 }
207}
208
209pub struct Trim(pub &'static str, pub &'static str);
213
214impl Pipe for Trim {
215 type Input = String;
216 type Output = proc_macro2::Ident;
217
218 fn pipe(&self, input: String) -> proc_macro2::Ident {
219 let trimmed = input
220 .trim_start_matches(|c: char| self.0.contains(c))
221 .trim_end_matches(|c: char| self.1.contains(c));
222 proc_macro2::Ident::new(trimmed, proc_macro2::Span::call_site())
223 }
224}
225
226pub struct Plural;
230
231impl Pipe for Plural {
232 type Input = String;
233 type Output = proc_macro2::Ident;
234
235 fn pipe(&self, input: String) -> proc_macro2::Ident {
236 let result = if input.ends_with('y')
237 && input
238 .chars()
239 .rev()
240 .nth(1)
241 .is_some_and(|c| !"aeiou".contains(c))
242 {
243 format!("{}ies", &input[..input.len() - 1])
244 } else if input.ends_with('s')
245 || input.ends_with('x')
246 || input.ends_with('z')
247 || input.ends_with("ch")
248 || input.ends_with("sh")
249 {
250 format!("{}es", input)
251 } else {
252 format!("{}s", input)
253 };
254 proc_macro2::Ident::new(&result, proc_macro2::Span::call_site())
255 }
256}
257
258pub struct Singular;
262
263impl Pipe for Singular {
264 type Input = String;
265 type Output = proc_macro2::Ident;
266
267 fn pipe(&self, input: String) -> proc_macro2::Ident {
268 let result = if input.ends_with("ies") {
269 format!("{}y", &input[..input.len() - 3])
270 } else if input.ends_with("ses")
271 || input.ends_with("xes")
272 || input.ends_with("zes")
273 || input.ends_with("ches")
274 || input.ends_with("shes")
275 {
276 input[..input.len() - 2].to_string()
277 } else if input.ends_with('s') && !input.ends_with("ss") {
278 input[..input.len() - 1].to_string()
279 } else {
280 input
281 };
282 proc_macro2::Ident::new(&result, proc_macro2::Span::call_site())
283 }
284}