Skip to content

Instantly share code, notes, and snippets.

@breezewish
Created February 3, 2019 08:29
Show Gist options
  • Select an option

  • Save breezewish/a337f36b58b282d912a31cb5d3031a88 to your computer and use it in GitHub Desktop.

Select an option

Save breezewish/a337f36b58b282d912a31cb5d3031a88 to your computer and use it in GitHub Desktop.

Revisions

  1. breezewish created this gist Feb 3, 2019.
    52 changes: 52 additions & 0 deletions simple-maco.rs
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,52 @@
    extern crate proc_macro;

    use quote::quote;
    use proc_macro::TokenStream;
    use syn::*;
    use syn::parse::{Parse, ParseStream};

    #[derive(Debug)]
    struct MetricDefinition {
    vis: Visibility,
    name: Ident,
    values: Vec<Ident>,
    }

    impl Parse for MetricDefinition {
    fn parse(input: ParseStream) -> Result<Self> {
    let vis = input.parse::<Visibility>()?;
    input.parse::<Token![struct]>()?;
    let name = input.parse::<Ident>()?;
    let content; braced!(content in input);
    let values = content
    .parse_terminated::<_, Token![,]>(Ident::parse)?
    .into_iter()
    .collect();
    Ok(Self { vis, name, values })
    }
    }

    #[proc_macro]
    pub fn make_metrics(input: TokenStream) -> TokenStream {
    let data = parse_macro_input!(input as MetricDefinition);
    let vis = &data.vis;
    let name = &data.name;
    let values = &data.values;
    let values_str = data.values.iter().map(|ident| LitStr::new(
    &ident.to_string(),
    ident.span(),
    ));
    let expanded = quote! {
    #vis struct #name {
    #(#values: Counter,)*
    }
    impl #name {
    pub fn new() -> Self {
    Self {
    #(#values: COUNTER.with_label_values(&[#values_str]),)*
    }
    }
    }
    };
    TokenStream::from(expanded)
    }