Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
A simple procedural macro that generates a static metric for rust-prometheus.
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)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment