1use crate::monitoring_status::MonitoringStatus;
2use crate::Perfdata;
3use std::fmt::{Display, Formatter};
4
5#[derive(Debug, Default, PartialEq)]
9pub struct PerfdataSet<'a> {
10 data: Vec<Perfdata<'a>>,
11}
12
13impl<'a> PerfdataSet<'a> {
14 pub fn new() -> Self {
16 PerfdataSet::default()
17 }
18
19 pub fn add(&mut self, pd: Perfdata<'a>) {
21 self.data.push(pd);
22 }
23
24 pub fn is_empty(&self) -> bool {
26 self.data.is_empty()
27 }
28
29 pub fn data(&self) -> impl Iterator<Item = &Perfdata<'a>> {
31 self.data.iter()
32 }
33
34 pub fn critical(&self) -> impl Iterator<Item = &Perfdata<'a>> {
36 self.data().filter(|pd| pd.is_crit())
37 }
38
39 pub fn has_critical(&self) -> bool {
42 self.critical().next().is_some()
43 }
44
45 pub fn warning(&self) -> impl Iterator<Item = &Perfdata<'a>> {
47 self.data().filter(|pd| pd.is_warn())
48 }
49
50 pub fn has_warning(&self) -> bool {
53 self.warning().next().is_some()
54 }
55
56 pub fn status(&self) -> MonitoringStatus {
59 if self.has_critical() {
60 MonitoringStatus::Critical
61 } else if self.has_warning() {
62 MonitoringStatus::Warning
63 } else {
64 MonitoringStatus::OK
65 }
66 }
67}
68
69impl<'a> From<Vec<Perfdata<'a>>> for PerfdataSet<'a> {
70 fn from(data: Vec<Perfdata<'a>>) -> Self {
71 Self { data }
72 }
73}
74
75impl<'a> FromIterator<Perfdata<'a>> for PerfdataSet<'a> {
76 fn from_iter<T: IntoIterator<Item = Perfdata<'a>>>(iter: T) -> Self {
77 Self {
78 data: iter.into_iter().collect(),
79 }
80 }
81}
82
83impl<'a> Display for PerfdataSet<'a> {
84 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
85 for (i, pd) in self.data.iter().enumerate() {
86 write!(f, "{}", pd)?;
87 if i != self.data.len() - 1 {
88 write!(f, " ")?;
89 }
90 }
91 Ok(())
92 }
93}
94
95#[cfg(test)]
96mod tests {
97 use super::*;
98 use crate::ThresholdRange;
99
100 #[test]
101 fn display_pdset() {
102 let thc = ThresholdRange::above_pos(23);
104 let thw = ThresholdRange::inside(0, 100);
105 let pd = Perfdata::bytes("bytes", 42)
106 .with_warn(thw)
107 .with_crit(thc)
108 .with_min(-100)
109 .with_max(100);
110
111 let pdo = Perfdata::unit("unit", 50);
112 let pdu = Perfdata::undetermined("undetermined");
113
114 let mut pds = PerfdataSet::new();
115 pds.add(pd);
116 pds.add(pdo);
117 pds.add(pdu);
118
119 let empty_pds = PerfdataSet::new();
120
121 let result = pds.to_string();
123 let expected = "'bytes'=42b;@100;23;-100;100; 'unit'=50; 'undetermined'=U;";
124
125 let empty_result = empty_pds.to_string();
126
127 assert_eq!(&empty_result, "");
129 assert_eq!(&result, expected);
130 }
131
132 #[test]
133 fn test_degraded() {
134 let val = 10;
135 let pds = vec![
136 Perfdata::unit("critical", val).with_crit(ThresholdRange::above_pos(0)),
137 Perfdata::unit("warn", val).with_warn(ThresholdRange::above_pos(0)),
138 Perfdata::unit("ok", val),
139 ];
140
141 let pds_crit: PerfdataSet = pds[..].iter().cloned().collect();
142 let pds_warn: PerfdataSet = pds[1..].iter().cloned().collect();
143 let pds_ok: PerfdataSet = pds[2..].iter().cloned().collect();
144
145 assert_eq!(pds_crit.data().count(), 3);
146 assert_eq!(pds_warn.data().count(), 2);
147 assert_eq!(pds_ok.data().count(), 1);
148
149 assert_eq!(pds_crit.critical().count(), 1);
150 assert_eq!(pds_warn.warning().count(), 1);
151 assert_eq!(pds_ok.critical().count(), 0);
152 assert_eq!(pds_ok.warning().count(), 0);
153 }
154}