Skip to main content

singularize_macro/
lib.rs

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}