fastmetrics_derive/lib.rs
1//! This crate provides some derive macros for `fastmetrics`.
2
3#![deny(missing_docs)]
4#![deny(unsafe_code)]
5// False positive: https://github.com/rust-lang/rust/issues/129637
6// #![deny(unused_crate_dependencies)]
7
8mod encode_label_set;
9mod encode_label_value;
10mod register;
11mod state_set_value;
12mod utils;
13
14use proc_macro::TokenStream;
15use syn::{parse_macro_input, DeriveInput, Error};
16
17/// Derive the `EncodeLabelSet` trait for structs.
18///
19/// This macro automatically implements the `EncodeLabelSet` trait,
20/// which allows the struct to be used as a set of metric labels.
21/// This is useful for creating structured label sets that can be attached to metrics.
22///
23/// # Example
24///
25/// ```rust
26/// # use fastmetrics_derive::EncodeLabelSet;
27/// #[derive(EncodeLabelSet)]
28/// struct MyLabels {
29/// service: String,
30/// endpoint: String,
31/// }
32/// ```
33#[proc_macro_derive(EncodeLabelSet)]
34pub fn derive_encode_label_set(input: TokenStream) -> TokenStream {
35 let input = parse_macro_input!(input as DeriveInput);
36 encode_label_set::expand_derive(input)
37 .unwrap_or_else(Error::into_compile_error)
38 .into()
39}
40
41// Derive the `EncodeLabelValue` trait for enums.
42///
43/// This macro generates an implementation of the `EncodeLabelValue` trait,
44/// which allows them to be used as values in metric labels.
45/// This is useful for ensuring type safety when using enumerated values as labels.
46///
47/// # Example
48///
49/// ```rust
50/// # use fastmetrics_derive::EncodeLabelValue;
51/// #[derive(EncodeLabelValue)]
52/// enum Status {
53/// Success,
54/// Error,
55/// Pending,
56/// }
57/// ```
58#[proc_macro_derive(EncodeLabelValue)]
59pub fn derive_encode_label_value(input: TokenStream) -> TokenStream {
60 let input = parse_macro_input!(input as DeriveInput);
61 encode_label_value::expand_derive(input)
62 .unwrap_or_else(Error::into_compile_error)
63 .into()
64}
65
66/// Derive the `StateSetValue` trait for enums.
67///
68/// This macro implements the `StateSetValue` trait, which allows an enum
69/// to be used as a value in a state set metric.
70///
71/// # Example
72///
73/// ```rust
74/// # use fastmetrics_derive::StateSetValue;
75/// #[derive(PartialEq, StateSetValue)]
76/// enum ServiceState {
77/// Available,
78/// Degraded,
79/// Down,
80/// }
81/// ```
82#[proc_macro_derive(StateSetValue)]
83pub fn derive_state_set_value(input: TokenStream) -> TokenStream {
84 let input = parse_macro_input!(input as DeriveInput);
85 state_set_value::expand_derive(input)
86 .unwrap_or_else(Error::into_compile_error)
87 .into()
88}
89
90/// Derive the `Register` trait for structs.
91///
92/// This macro implements automatic registration of metrics with a registry.
93/// It processes `#[register]` attributes on struct fields to configure how
94/// each metric should be registered.
95///
96/// # Example
97///
98/// ```rust
99/// # use std::marker::PhantomData;
100/// # use fastmetrics::{
101/// # format::text,
102/// # metrics::{counter::Counter, histogram::Histogram},
103/// # registry::{Register, Registry},
104/// # };
105/// #[derive(Default, fastmetrics_derive::Register)]
106/// struct Metrics {
107/// /// Total HTTP requests
108/// http_requests: Counter,
109///
110/// /// Duration of HTTP requests
111/// #[register(rename = "http_request_duration", unit(Seconds))]
112/// request_duration: Histogram,
113///
114/// #[register(flatten)]
115/// inner: InnerMetrics,
116///
117/// #[register(skip)]
118/// _skip: ()
119/// }
120///
121/// #[derive(Default, fastmetrics_derive::Register)]
122/// struct InnerMetrics {
123/// /// Inner counter help
124/// inner_counter: Counter,
125/// }
126///
127/// let mut registry = Registry::default();
128///
129/// let metrics = Metrics::default();
130/// metrics.register(&mut registry).unwrap();
131///
132/// let mut output = String::new();
133/// text::encode(&mut output, ®istry).unwrap();
134/// // println!("{}", output);
135/// ```
136#[proc_macro_derive(Register, attributes(register))]
137pub fn derive_register_derive(input: TokenStream) -> TokenStream {
138 let input = parse_macro_input!(input as DeriveInput);
139 register::expand_derive(input).unwrap_or_else(Error::into_compile_error).into()
140}