macron_map/
lib.rs

1//! See the documentation here [macron documentation](https://docs.rs/macron)
2
3use proc_macro::TokenStream;
4use quote::quote;
5use syn::punctuated::Punctuated;
6
7/// The key-value collection parser
8#[proc_macro]
9pub fn map(input: TokenStream) -> TokenStream {
10    let Map { fields } = syn::parse_macro_input!(input as Map);
11    
12    let list = fields.into_iter().map(|pair| {
13        let (k, v) = (pair.key, pair.value);
14        quote! { (#k, #v) }
15    });
16
17    quote! { [#(#list),*] }.into()
18}
19
20/// The key-value collection
21struct Map {
22    pub fields: Punctuated::<Field, syn::Token![,]>,
23}
24
25impl syn::parse::Parse for Map {
26    fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
27        let fields = Punctuated::<Field, syn::Token![,]>::parse_terminated(input)?;
28        
29        Ok(Map { fields })
30    }
31}
32
33/// The key-value collection field
34struct Field {
35    pub key: syn::Expr,
36    pub value: syn::Expr,
37}
38
39impl syn::parse::Parse for Field {
40    fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
41        let key = input.parse()?;
42
43        if input.peek(syn::Token![:]) {
44            input.parse::<syn::Token![:]>()?;
45        } else if input.peek(syn::Token![=>]) {
46            input.parse::<syn::Token![=>]>()?;
47        } else {
48            return Err(syn::Error::new(input.span(), "the expected separator is `:` or `=>` between key and value"));
49        }
50
51        let value = input.parse()?;
52        
53        Ok(Field {
54            key,
55            value,
56        })
57    }
58}