1use proc_macro::{TokenStream, TokenTree};
2
3#[proc_macro]
9pub fn inject(input: TokenStream) -> TokenStream {
10 let mut it = input.into_iter();
11 let input = if let Some(TokenTree::Literal(l)) = it.next() {
12 if it.next().is_some() {
13 panic!("only one argument is expected")
14 }
15 l.to_string()
16 } else {
17 panic!("&str is expected")
18 };
19
20 let (front, back) = ("#{", "}#");
21
22 let mut v = Vec::new();
23
24 let (fstr, fargs) = input
25 .split(front)
26 .flat_map(|s| {
27 let parts: Vec<&str> = s.split(back).collect();
28 let (last, inner) = parts.split_last().unwrap();
29 v.push((inner.join(back), last.to_string()));
30 [inner.join(back), last.to_string()].into_iter()
31 })
32 .skip(1)
33 .enumerate()
34 .fold((String::new(), String::new()), |(fstr, fargs), (i, x)| {
35 if i % 2 == 0 {
36 (format!("{fstr}{x}"), fargs)
37 } else {
38 (format!("{fstr}{{}}"), format!("{fargs}, {x}"))
39 }
40 });
41
42 format!(r#"format!({fstr}{fargs})"#).parse().unwrap()
45}