Skip to main content

torrust_metrics/label/
value.rs

1use derive_more::Display;
2use serde::{Deserialize, Serialize};
3
4use crate::prometheus::PrometheusSerializable;
5
6#[derive(Debug, Display, Clone, Eq, PartialEq, Default, Deserialize, Serialize, Hash, Ord, PartialOrd)]
7pub struct LabelValue(String);
8
9impl LabelValue {
10    #[must_use]
11    pub fn new(value: &str) -> Self {
12        Self(value.to_owned())
13    }
14
15    /// Empty label values are ignored in Prometheus.
16    #[must_use]
17    // `Self(String::default())` and `Self(Default::default())` are observationally
18    // identical because `String::default()` is an empty string.
19    #[cfg_attr(test, mutants::skip)]
20    pub fn ignore() -> Self {
21        Self(String::default())
22    }
23}
24
25impl PrometheusSerializable for LabelValue {
26    fn to_prometheus(&self) -> String {
27        self.0.clone()
28    }
29}
30
31impl From<String> for LabelValue {
32    fn from(value: String) -> Self {
33        Self(value)
34    }
35}
36
37#[cfg(test)]
38mod tests {
39    use std::collections::hash_map::DefaultHasher;
40    use std::hash::Hash;
41
42    use crate::label::value::LabelValue;
43    use crate::prometheus::PrometheusSerializable;
44
45    #[test]
46    fn it_serializes_to_prometheus() {
47        let label_value = LabelValue::new("value");
48        assert_eq!(label_value.to_prometheus(), "value");
49    }
50
51    #[test]
52    fn it_could_be_initialized_from_str() {
53        let lv = LabelValue::new("abc");
54        assert_eq!(lv.0, "abc");
55    }
56
57    #[test]
58    fn it_should_allow_to_create_an_ignored_label_value() {
59        let lv = LabelValue::ignore();
60        assert_eq!(lv.0, "");
61    }
62
63    #[test]
64    fn it_should_be_converted_from_string() {
65        let s = String::from("foo");
66        let lv: LabelValue = s.clone().into();
67        assert_eq!(lv.0, s);
68    }
69
70    #[test]
71    fn it_should_be_comparable() {
72        let a = LabelValue::new("x");
73        let b = LabelValue::new("x");
74        let c = LabelValue::new("y");
75
76        assert_eq!(a, b);
77        assert_ne!(a, c);
78    }
79
80    #[test]
81    fn it_should_be_allow_ordering() {
82        let a = LabelValue::new("x");
83        let b = LabelValue::new("y");
84
85        assert!(a < b);
86    }
87
88    #[test]
89    fn it_should_be_hashable() {
90        let a = LabelValue::new("x");
91        let mut hasher = DefaultHasher::new();
92        a.hash(&mut hasher);
93    }
94
95    #[test]
96    fn it_should_implement_clone() {
97        let a = LabelValue::new("x");
98        let _unused = a.clone();
99    }
100
101    #[test]
102    fn it_should_implement_display() {
103        let a = LabelValue::new("x");
104        assert_eq!(format!("{a}"), "x");
105    }
106}