scuffle_metrics_derive/lib.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
#![doc = include_str!("../README.md")]
use enum_impl::metric_enum_impl;
use metrics_impl::metrics_impl;
use proc_macro::TokenStream;
mod enum_impl;
mod metrics_impl;
/// A macro used to create metric handlers.
///
/// You can change the crate by specifying `#[metrics(crate = "...")]`.
///
/// Attributes:
///
/// - `crate`: The `scuffle_metrics` crate path. Valid on modules & functions.
/// - `builder`: The builder to use for the metric. Valid on functions.
/// - `unit`: The unit of the metric. Valid on functions.
/// - `rename`: The name of the metric. Valid on modules, functions & function
/// arguments.
///
/// When using the module, you do not need to attribute each function with the
/// `#[metrics]` attribute. All non function definitions are ignored.
///
/// # Module Example
///
/// ```rust
/// #[metrics]
/// mod example {
/// use scuffle_metrics::{CounterU64, MetricEnum};
///
/// #[derive(MetricEnum)]
/// pub enum Kind {
/// Http,
/// Grpc,
/// }
///
/// #[metrics(unit = "requests")]
/// pub fn request(kind: Kind) -> CounterU64;
/// }
///
/// example::request(Kind::Http).incr();
/// ```
///
/// # Function Example
///
/// ```rust
/// #[metrics(unit = "requests")]
/// pub fn request(kind: Kind) -> CounterU64;
///
/// request(Kind::Http).incr();
/// ```
#[proc_macro_attribute]
pub fn metrics(args: TokenStream, input: TokenStream) -> TokenStream {
match metrics_impl(args, input) {
Ok(tokens) => tokens.into(),
Err(err) => err.to_compile_error().into(),
}
}
/// Implements a conversion `Into<opentelemetry::Value>` for the enum.
/// This allows the enum to be used as a metric label.
#[proc_macro_derive(MetricEnum, attributes(metrics))]
pub fn metric_enum(input: TokenStream) -> TokenStream {
match metric_enum_impl(input.into()) {
Ok(tokens) => tokens.into(),
Err(err) => err.to_compile_error().into(),
}
}