metrics_util/
kind.rs

1use std::ops::BitOr;
2
3/// Metric kind.
4///
5/// Defines the kind, or type, of a metric.  Follows the supported metric types of `metrics`:
6/// - counters
7/// - gauges
8/// - histograms
9#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, PartialOrd, Ord)]
10pub enum MetricKind {
11    /// Counter type.
12    Counter,
13    /// Gauge type.
14    Gauge,
15    /// Histogram type.
16    Histogram,
17}
18
19/// Metric kind mask.
20///
21/// Useful for matching against a kind, or kinds, of metrics.
22///
23/// In order to use for defining multiple metric kinds, can be used in a bitmask fashion, as this
24/// type implements bitwise OR support, and checking for inclusion of a specific kind within another
25/// kind value can be checked via [`matches`](MetricKindMask::matches):
26///
27/// ```rust
28/// # use metrics_util::{MetricKind, MetricKindMask};
29/// # fn main() {
30/// // Let's only match counters and histograms:
31/// let mask = MetricKindMask::COUNTER | MetricKindMask::HISTOGRAM;
32///
33/// // And check to see if the kinds we have matches our mask:
34/// assert!(!mask.matches(MetricKind::Gauge));
35/// assert!(mask.matches(MetricKind::Counter));
36///
37/// // There's even two handy versions to avoid extra typing:
38/// let none_mask = MetricKindMask::NONE;
39/// let all_mask = MetricKindMask::ALL;
40///
41/// assert!(!none_mask.matches(MetricKind::Counter));
42/// assert!(!none_mask.matches(MetricKind::Gauge));
43/// assert!(!none_mask.matches(MetricKind::Histogram));
44/// assert!(all_mask.matches(MetricKind::Counter));
45/// assert!(all_mask.matches(MetricKind::Gauge));
46/// assert!(all_mask.matches(MetricKind::Histogram));
47/// # }
48/// ```
49#[derive(Debug, Eq, PartialEq, Hash, Clone, Copy, Ord, PartialOrd)]
50pub struct MetricKindMask(u8);
51
52impl MetricKindMask {
53    /// No metric kinds.
54    pub const NONE: MetricKindMask = MetricKindMask(0);
55
56    /// The counter kind.
57    pub const COUNTER: MetricKindMask = MetricKindMask(1);
58
59    /// The gauge kind.
60    pub const GAUGE: MetricKindMask = MetricKindMask(2);
61
62    /// The histogram kind.
63    pub const HISTOGRAM: MetricKindMask = MetricKindMask(4);
64
65    /// All metric kinds.
66    pub const ALL: MetricKindMask = MetricKindMask(7);
67
68    #[inline]
69    fn value(&self) -> u8 {
70        self.0
71    }
72
73    /// Whether or not this metric kind contains the specified kind.
74    pub fn matches(&self, kind: MetricKind) -> bool {
75        match kind {
76            MetricKind::Counter => self.0 & MetricKindMask::COUNTER.value() != 0,
77            MetricKind::Gauge => self.0 & MetricKindMask::GAUGE.value() != 0,
78            MetricKind::Histogram => self.0 & MetricKindMask::HISTOGRAM.value() != 0,
79        }
80    }
81}
82
83impl BitOr for MetricKindMask {
84    type Output = Self;
85
86    fn bitor(self, rhs: Self) -> Self::Output {
87        Self(self.0 | rhs.0)
88    }
89}
90
91#[cfg(test)]
92mod tests {
93    use super::MetricKindMask;
94    use crate::MetricKind;
95
96    #[test]
97    fn test_matching() {
98        let cmask = MetricKindMask::COUNTER;
99        let gmask = MetricKindMask::GAUGE;
100        let hmask = MetricKindMask::HISTOGRAM;
101        let nmask = MetricKindMask::NONE;
102        let amask = MetricKindMask::ALL;
103
104        assert!(cmask.matches(MetricKind::Counter));
105        assert!(!cmask.matches(MetricKind::Gauge));
106        assert!(!cmask.matches(MetricKind::Histogram));
107
108        assert!(!gmask.matches(MetricKind::Counter));
109        assert!(gmask.matches(MetricKind::Gauge));
110        assert!(!gmask.matches(MetricKind::Histogram));
111
112        assert!(!hmask.matches(MetricKind::Counter));
113        assert!(!hmask.matches(MetricKind::Gauge));
114        assert!(hmask.matches(MetricKind::Histogram));
115
116        assert!(amask.matches(MetricKind::Counter));
117        assert!(amask.matches(MetricKind::Gauge));
118        assert!(amask.matches(MetricKind::Histogram));
119
120        assert!(!nmask.matches(MetricKind::Counter));
121        assert!(!nmask.matches(MetricKind::Gauge));
122        assert!(!nmask.matches(MetricKind::Histogram));
123    }
124}