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