use proc_macro::TokenStream;
use proc_macro2::TokenStream as TokenStream2;
use quote::quote;
use syn::{parse_macro_input, parse::Parse, Token, Ident, LitStr};
use crate::transform::transform_tokens;
struct MetaInput {
params: syn::punctuated::Punctuated<MetaParam, Token![,]>,
body: TokenStream2,
}
struct MetaParam {
name: Ident,
_eq: Token![=],
value: LitStr,
}
impl Parse for MetaParam {
fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
Ok(MetaParam {
name: input.parse()?,
_eq: input.parse()?,
value: input.parse()?,
})
}
}
impl Parse for MetaInput {
fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
let content;
syn::parenthesized!(content in input);
let params = content.parse_terminated(MetaParam::parse, Token![,])?;
let body: TokenStream2 = input.parse()?;
Ok(MetaInput { params, body })
}
}
pub fn main(input: TokenStream) -> TokenStream {
let parsed = parse_macro_input!(input as MetaInput);
let params: Vec<(String, String)> = parsed.params
.into_iter()
.map(|p| (p.name.to_string(), p.value.value()))
.collect();
let transformed = transform_tokens(parsed.body, ¶ms);
quote! { #transformed }.into()
}