s_macro/lib.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
extern crate proc_macro;
use proc_macro::TokenStream;
use quote::quote;
use syn::{Expr, Lit};
/// Convenient way of making a `String`.
///
/// 1. `s!()`
/// 2. `s!(123 + 321)`
/// 3. `s!("hello, {}", "world")`
///
/// # Examples
///
/// ```
/// use s_macro::s;
///
/// assert!(s!() == String::new());
/// assert!(s!("hello, world") == String::from("hello, world"));
/// assert!(s!(123 + 321) == format!("{}", 123 + 321));
///
/// let world = "world";
/// assert!(s!("hello, {}", world) == format!("hello, {}", world));
/// assert!(s!("hello, {world}") == format!("hello, {world}"));
/// ```
#[proc_macro]
pub fn s(input: TokenStream) -> TokenStream {
if input.is_empty() {
quote! { String::new() }.into()
}
else if let Ok(expr) = syn::parse::<Expr>(input.clone()) {
if let Expr::Lit(ref lit) = expr {
if let Lit::Str(_) = lit.lit {
return quote! { format!(#expr) }.into();
}
}
quote! { format!("{}", #expr) }.into()
}
else {
let input = proc_macro2::TokenStream::from(input);
quote! { format!(#input) }.into()
}
}