toml_query_derive/
lib.rs

1#![warn(rust_2018_idioms)]
2
3extern crate proc_macro;
4
5use proc_macro::TokenStream;
6use quote::quote;
7use syn::{Lit, Meta, MetaNameValue};
8
9#[proc_macro_derive(Partial, attributes(location))]
10pub fn derive_partial(tokens: TokenStream) -> TokenStream {
11    let ast: syn::DeriveInput = syn::parse(tokens).unwrap();
12    let mut location: Option<String> = None;
13    let name = &ast.ident;
14
15    // Iterate over the struct's #[...] attributes
16    for option in ast.attrs.into_iter() {
17        let option = option.parse_meta().unwrap();
18        match option {
19            // Match '#[ident = lit]' attributes. Match guard makes it '#[prefix = lit]'
20            Meta::NameValue(MetaNameValue {
21                ref path, ref lit, ..
22            }) if path.is_ident("location") => {
23                if let Lit::Str(lit) = lit {
24                    location = Some(lit.value());
25                }
26            }
27            _ => {} // ...
28        }
29    }
30
31    let location = location.unwrap();
32
33    let gen = quote! {
34        impl<'a> ::toml_query::read::Partial<'a> for #name {
35            const LOCATION : &'static str = #location;
36            type  Output                  = Self;
37        }
38    };
39
40    gen.into()
41}