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(),
	}
}