Skip to main content

fast_telemetry/metric/
label.rs

1//! Label trait for enum-indexed metrics.
2//!
3//! Labels provide O(1) dimensional metrics without HashMap lookups.
4//! Each label enum variant maps directly to an array index.
5
6use std::fmt::Debug;
7
8/// Trait for label enums used with `LabeledCounter`, `LabeledGauge`, etc.
9///
10/// Implementing this trait allows an enum to be used as a dimension for metrics.
11/// Each variant maps to an array index, enabling O(1) metric lookup and update.
12///
13/// # Example
14///
15/// ```ignore
16/// #[derive(Copy, Clone, Debug)]
17/// enum HttpMethod {
18///     Get,
19///     Post,
20///     Put,
21///     Delete,
22///     Other,
23/// }
24///
25/// impl LabelEnum for HttpMethod {
26///     const CARDINALITY: usize = 5;
27///     const LABEL_NAME: &'static str = "method";
28///
29///     fn as_index(self) -> usize {
30///         self as usize
31///     }
32///
33///     fn from_index(index: usize) -> Self {
34///         match index {
35///             0 => Self::Get,
36///             1 => Self::Post,
37///             2 => Self::Put,
38///             3 => Self::Delete,
39///             _ => Self::Other,
40///         }
41///     }
42///
43///     fn variant_name(self) -> &'static str {
44///         match self {
45///             Self::Get => "get",
46///             Self::Post => "post",
47///             Self::Put => "put",
48///             Self::Delete => "delete",
49///             Self::Other => "other",
50///         }
51///     }
52/// }
53/// ```
54pub trait LabelEnum: Copy + Debug + 'static {
55    /// Number of variants in this enum.
56    const CARDINALITY: usize;
57
58    /// The Prometheus label name for this dimension.
59    ///
60    /// E.g., "method" for HttpMethod, "command" for RedisCommand.
61    const LABEL_NAME: &'static str;
62
63    /// Convert this variant to its array index.
64    fn as_index(self) -> usize;
65
66    /// Convert an array index back to a variant.
67    ///
68    /// Used for iteration during export. Should handle out-of-bounds
69    /// by returning a sensible default (e.g., an "Other" variant).
70    fn from_index(index: usize) -> Self;
71
72    /// Get the Prometheus label value for this variant.
73    ///
74    /// Should be lowercase, snake_case for Prometheus compatibility.
75    fn variant_name(self) -> &'static str;
76
77    /// Get the label name (convenience method for accessing LABEL_NAME).
78    #[inline]
79    fn label_name(&self) -> &'static str {
80        Self::LABEL_NAME
81    }
82}