scuffle_metrics_derive/lib.rs
1//! A proc-macro to derive the `#[metrics]` attribute and the
2//! `#[derive(MetricEnum)]` attribute.
3//!
4//! For more information checkout the [`scuffle-metrics`](https://docs.rs/scuffle-metrics)
5//! crate.
6//!
7//! ## License
8//!
9//! This project is licensed under the MIT or Apache-2.0 license.
10//! You can choose between one of them if you use this work.
11//!
12//! `SPDX-License-Identifier: MIT OR Apache-2.0`
13#![deny(missing_docs)]
14#![deny(unsafe_code)]
15#![deny(unreachable_pub)]
16
17use enum_impl::metric_enum_impl;
18use metrics_impl::metrics_impl;
19use proc_macro::TokenStream;
20
21mod enum_impl;
22mod metrics_impl;
23
24/// A macro used to create metric handlers.
25///
26/// You can change the crate by specifying `#[metrics(crate_path = "...")]`.
27///
28/// Module Attributes:
29///
30/// - `crate_path`: The `scuffle_metrics` crate path.
31/// - `rename`: The name of the metric container.
32///
33/// Function Attributes:
34///
35/// - `crate_path`: The `scuffle_metrics` crate path.
36/// - `builder`: The builder to use for the metric.
37/// - `unit`: The unit of the metric.
38/// - `rename`: The name of the metric.
39///
40/// Function Arguments Attributes:
41///
42/// - `rename`: The name of the argument.
43///
44/// When using the module, you do not need to attribute each function with the
45/// `#[metrics]` attribute. All non function definitions are ignored.
46///
47/// # Module Example
48///
49/// ```rust
50/// #[scuffle_metrics::metrics]
51/// mod example {
52/// use scuffle_metrics::{MetricEnum, collector::CounterU64};
53///
54/// #[derive(MetricEnum)]
55/// pub enum Kind {
56/// Http,
57/// Grpc,
58/// }
59///
60/// #[metrics(unit = "requests")]
61/// pub fn request(kind: Kind) -> CounterU64;
62/// }
63///
64/// // Increment the counter
65/// example::request(example::Kind::Http).incr();
66/// ```
67///
68/// # Function Example
69///
70/// ```rust
71/// # use scuffle_metrics::{MetricEnum, collector::CounterU64};
72/// # #[derive(MetricEnum)]
73/// # pub enum Kind {
74/// # Http,
75/// # Grpc,
76/// # }
77/// #[scuffle_metrics::metrics(unit = "requests")]
78/// pub fn request(kind: Kind) -> CounterU64;
79///
80/// // Increment the counter
81/// request(Kind::Http).incr();
82/// ```
83#[proc_macro_attribute]
84pub fn metrics(args: TokenStream, input: TokenStream) -> TokenStream {
85 match metrics_impl(args, input) {
86 Ok(tokens) => tokens.into(),
87 Err(err) => err.to_compile_error().into(),
88 }
89}
90
91/// Implements a conversion `Into<opentelemetry::Value>` for the enum.
92/// This allows the enum to be used as a metric label.
93///
94/// You can change the crate by specifying `#[metrics(crate_path = "...")]`.
95///
96/// Enum Attributes:
97///
98/// - `crate_path`: The `scuffle_metrics` crate path.
99///
100/// Enum Variant Attributes:
101///
102/// - `rename`: The name of the metric.
103#[proc_macro_derive(MetricEnum, attributes(metrics))]
104pub fn metric_enum(input: TokenStream) -> TokenStream {
105 match metric_enum_impl(input.into()) {
106 Ok(tokens) => tokens.into(),
107 Err(err) => err.to_compile_error().into(),
108 }
109}