saluki_core/data_model/event/metric/value/
set.rs1use std::{collections::HashSet, fmt, num::NonZeroU64};
2
3use super::{
4 iter::{PointsIter, PointsIterRef},
5 TimestampedValue, TimestampedValues,
6};
7
8#[derive(Clone, Debug, Eq, PartialEq)]
16pub struct SetPoints(TimestampedValues<HashSet<String>, 1>);
17
18impl SetPoints {
19 pub(super) fn inner(&self) -> &TimestampedValues<HashSet<String>, 1> {
20 &self.0
21 }
22
23 pub(super) fn inner_mut(&mut self) -> &mut TimestampedValues<HashSet<String>, 1> {
24 &mut self.0
25 }
26
27 pub(super) fn drain_timestamped(&mut self) -> Self {
28 Self(self.0.drain_timestamped())
29 }
30
31 pub(super) fn split_at_timestamp(&mut self, timestamp: u64) -> Option<Self> {
32 self.0.split_at_timestamp(timestamp).map(Self)
33 }
34
35 pub fn is_empty(&self) -> bool {
37 self.0.values.is_empty()
38 }
39
40 pub fn len(&self) -> usize {
42 self.0.values.len()
43 }
44
45 pub fn merge(&mut self, other: Self) {
50 let mut needs_sort = false;
51 for other_value in other.0.values {
52 if let Some(existing_value) = self
53 .0
54 .values
55 .iter_mut()
56 .find(|value| value.timestamp == other_value.timestamp)
57 {
58 existing_value.value.extend(other_value.value);
59 } else {
60 self.0.values.push(other_value);
61 needs_sort = true;
62 }
63 }
64
65 if needs_sort {
66 self.0.sort_by_timestamp();
67 }
68 }
69}
70
71impl From<String> for SetPoints {
72 fn from(value: String) -> Self {
73 Self(TimestampedValue::from(HashSet::from([value])).into())
74 }
75}
76
77impl<'a> From<&'a str> for SetPoints {
78 fn from(value: &'a str) -> Self {
79 Self(TimestampedValue::from(HashSet::from([value.to_string()])).into())
80 }
81}
82
83impl<'a> From<(u64, &'a str)> for SetPoints {
84 fn from((ts, value): (u64, &'a str)) -> Self {
85 Self(TimestampedValue::from((ts, HashSet::from([value.to_string()]))).into())
86 }
87}
88
89impl<'a, const N: usize> From<[&'a str; N]> for SetPoints {
90 fn from(values: [&'a str; N]) -> Self {
91 Self(TimestampedValue::from(HashSet::from_iter(values.into_iter().map(|s| s.to_string()))).into())
92 }
93}
94
95impl<'a, const N: usize> From<(u64, [&'a str; N])> for SetPoints {
96 fn from((ts, values): (u64, [&'a str; N])) -> Self {
97 Self(TimestampedValue::from((ts, values.into_iter().map(|s| s.to_string()).collect())).into())
98 }
99}
100
101impl<'a, const N: usize> From<[(u64, &'a str); N]> for SetPoints {
102 fn from(values: [(u64, &'a str); N]) -> Self {
103 Self(
104 values
105 .iter()
106 .map(|(ts, value)| TimestampedValue::from((*ts, HashSet::from([value.to_string()]))))
107 .into(),
108 )
109 }
110}
111
112impl<'a, const N: usize> From<[(u64, &'a [&'a str]); N]> for SetPoints {
113 fn from(values: [(u64, &'a [&'a str]); N]) -> Self {
114 Self(
115 values
116 .iter()
117 .map(|(ts, values)| TimestampedValue::from((*ts, values.iter().map(|s| s.to_string()).collect())))
118 .into(),
119 )
120 }
121}
122
123impl IntoIterator for SetPoints {
124 type Item = (Option<NonZeroU64>, f64);
125 type IntoIter = PointsIter;
126
127 fn into_iter(self) -> Self::IntoIter {
128 PointsIter::set(self.0.values.into_iter())
129 }
130}
131
132impl<'a> IntoIterator for &'a SetPoints {
133 type Item = (Option<NonZeroU64>, f64);
134 type IntoIter = PointsIterRef<'a>;
135
136 fn into_iter(self) -> Self::IntoIter {
137 PointsIterRef::set(self.0.values.iter())
138 }
139}
140
141impl fmt::Display for SetPoints {
142 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
143 write!(f, "[")?;
144 for (i, point) in self.0.values.iter().enumerate() {
145 if i > 0 {
146 write!(f, ",")?;
147 }
148
149 let ts = point.timestamp.map(|ts| ts.get()).unwrap_or_default();
150 write!(f, "({}, [", ts)?;
151 for (j, value) in point.value.iter().enumerate() {
152 if j > 0 {
153 write!(f, ",")?;
154 }
155 write!(f, "{}", value)?;
156 }
157 write!(f, "])")?;
158 }
159 write!(f, "]")
160 }
161}