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