singularize-macro 0.2.0

Adds a simple `singularize!` macro that runs at compiletime
Documentation
use proc_macro::{Delimiter, TokenStream, TokenTree};
use quote::{format_ident, quote};
use singularize::singularize as singularize_;
use syn::{Ident, parse_macro_input};

#[proc_macro]
pub fn singularize(input: TokenStream) -> TokenStream {
  let plural = parse_macro_input!(input as Ident);
  let singular = format_ident!(
    "{}",
    singularize_(&plural.to_string()),
    span = plural.span()
  );
  quote! { #singular }.into()
}

#[proc_macro]
pub fn singularize_paste(input: TokenStream) -> TokenStream {
  input
    .into_iter()
    .map(|tt| {
      match tt {
        TokenTree::Group(group) if group.delimiter() == Delimiter::Bracket => {
          let stream = group.stream();
          let mut tokens = stream.into_iter();

          match (tokens.next(), tokens.next()) {
            (Some(TokenTree::Ident(plural)), None) => {
              singularize(TokenStream::from(TokenTree::Ident(plural)))
            }
            _ => panic!("Expected a single identifier inside brackets, e.g., [users]"),
          }
        }
        other => TokenStream::from(other),
      }
    })
    .collect()
}