sql_table_inject/
lib.rs

1use proc_macro::{TokenStream, TokenTree};
2
3/// Interpolates the string using any user defined interpolation expressions inside.
4/// The only argument is the interpolation string literal.
5///
6/// Opening and closing sequences of characters of interpolation expressions
7/// are `#{` and `}#` respectively.
8#[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    // panic!("{:?}", v);
43    // panic!("{}", format!(r#"format!({fstr}{fargs})"#));
44    format!(r#"format!({fstr}{fargs})"#).parse().unwrap()
45}