1use proc_macro::{Delimiter, TokenStream, TokenTree};
2use quote::{format_ident, quote};
3use singularize::singularize as singularize_;
4use syn::{Ident, parse_macro_input};
5
6#[proc_macro]
7pub fn singularize(input: TokenStream) -> TokenStream {
8 let plural = parse_macro_input!(input as Ident);
9 let singular = format_ident!(
10 "{}",
11 singularize_(&plural.to_string()),
12 span = plural.span()
13 );
14 quote! { #singular }.into()
15}
16
17#[proc_macro]
18pub fn singularize_paste(input: TokenStream) -> TokenStream {
19 input
20 .into_iter()
21 .map(|tt| {
22 match tt {
23 TokenTree::Group(group) if group.delimiter() == Delimiter::Bracket => {
24 let stream = group.stream();
25 let mut tokens = stream.into_iter();
26
27 match (tokens.next(), tokens.next()) {
28 (Some(TokenTree::Ident(plural)), None) => {
29 singularize(TokenStream::from(TokenTree::Ident(plural)))
30 }
31 _ => panic!("Expected a single identifier inside brackets, e.g., [users]"),
32 }
33 }
34 other => TokenStream::from(other),
35 }
36 })
37 .collect()
38}