1use std::collections::HashSet;
4use std::fmt;
5use std::iter::FromIterator;
6
7use super::expression::Expression;
8use super::misc::{PromDuration, Span, Subquery};
9use super::return_value::{LabelSetOp, ReturnKind, ReturnValue};
10
11#[derive(Debug, PartialEq, Eq, Clone, Copy)]
13pub enum LabelOp {
14 Equal,
15 NotEqual,
16 RegexEqual,
17 RegexNotEqual
18}
19
20impl fmt::Display for LabelOp {
21 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
22 write!(f, "{}", match self {
23 LabelOp::Equal => "=",
24 LabelOp::NotEqual => "!=",
25 LabelOp::RegexEqual => "=~",
26 LabelOp::RegexNotEqual => "!~"
27 })
28 }
29}
30
31#[derive(Debug, PartialEq, Eq, Clone)]
33pub struct Label {
34 pub key: String,
35 pub op: LabelOp,
36 pub value: String,
37
38 pub span: Option<Span>
39}
40
41impl Label {
42 pub fn new<S: Into<String>>(op: LabelOp, key: S, value: S) -> Self {
43 Label {
44 op,
45 key: key.into(),
46 value: value.into(),
47 span: None
48 }
49 }
50
51 pub fn equal<S: Into<String>>(key: S, value: S) -> Self {
52 Label::new(LabelOp::Equal, key, value)
53 }
54
55 pub fn not_equal<S: Into<String>>(key: S, value: S) -> Self {
56 Label::new(LabelOp::NotEqual, key, value)
57 }
58
59 pub fn regex_equal<S: Into<String>>(key: S, value: S) -> Self {
60 Label::new(LabelOp::RegexEqual, key, value)
61 }
62
63 pub fn regex_notequal<S: Into<String>>(key: S, value: S) -> Self {
64 Label::new(LabelOp::RegexNotEqual, key, value)
65 }
66
67 pub fn key<S: Into<String>>(mut self, key: S) -> Self {
68 self.key = key.into();
69 self
70 }
71
72 pub fn op(mut self, op: LabelOp) -> Self {
73 self.op = op;
74 self
75 }
76
77 pub fn value<S: Into<String>>(mut self, value: S) -> Self {
78 self.value = value.into();
79 self
80 }
81
82 pub fn span<S: Into<Span>>(mut self, span: S) -> Self {
83 self.span = Some(span.into());
84 self
85 }
86}
87
88impl fmt::Display for Label {
89 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
90 write!(f, "{}{}{:?}", self.key, self.op, self.value)
91 }
92}
93
94#[derive(Debug, PartialEq, Eq, Clone, Default)]
96pub struct Selector {
97 pub metric: Option<String>,
98 pub labels: Vec<Label>,
99 pub range: Option<PromDuration>,
100 pub offset: Option<PromDuration>,
101 pub subquery: Option<Subquery>,
102
103 pub span: Option<Span>
104}
105
106impl Selector {
107 pub fn new() -> Self {
108 Selector {
109 metric: None,
110 labels: vec![],
111 range: None,
112 offset: None,
113 subquery: None,
114 span: None
115 }
116 }
117
118 pub fn metric<S: Into<String>>(mut self, metric: S) -> Self {
120 self.metric = Some(metric.into());
121 self
122 }
123
124 pub fn clear_metric(mut self) -> Self {
126 self.metric = None;
127 self
128 }
129
130 pub fn label(mut self, label: Label) -> Self {
132 self.labels.push(label);
133 self
134 }
135
136 pub fn labels(mut self, labels: Vec<Label>) -> Self {
138 self.labels = labels;
139 self
140 }
141
142 pub fn clear_labels(mut self) -> Self {
144 self.labels.clear();
145 self
146 }
147
148 pub fn range(mut self, range: PromDuration) -> Self {
150 self.range = Some(range);
151 self
152 }
153
154 pub fn clear_range(mut self) -> Self {
156 self.range = None;
157 self
158 }
159
160 pub fn offset(mut self, offset: PromDuration) -> Self {
162 self.offset = Some(offset);
163 self
164 }
165
166 pub fn clear_offset(mut self) -> Self {
167 self.offset = None;
168 self
169 }
170
171 pub fn subquery(mut self, subquery: Subquery) -> Self {
172 self.subquery = Some(subquery);
173 self
174 }
175
176 pub fn clear_subquery(mut self) -> Self {
177 self.subquery = None;
178 self
179 }
180
181 pub fn span<S: Into<Span>>(mut self, span: S) -> Self {
182 self.span = Some(span.into());
183 self
184 }
185
186 pub fn wrap(self) -> Expression {
187 Expression::Selector(self)
188 }
189
190 pub fn return_value(&self) -> ReturnValue {
191 let kind = match (self.range.is_some(), self.subquery.is_some()) {
192 (false, false) => ReturnKind::InstantVector,
193 (false, true) => ReturnKind::RangeVector,
194 (true, false) => ReturnKind::RangeVector,
195
196 (true, true) => ReturnKind::unknown(
198 "range and subquery are not allowed together",
199 self.clone().wrap()
200 )
201 };
202
203 let mut label_ops = Vec::new();
206 if !self.labels.is_empty() {
207 label_ops.push(LabelSetOp::append(
208 self.clone().wrap(),
209 self.span,
210 HashSet::from_iter(self.labels.iter().cloned().map(|l| l.key))
211 ));
212 }
213
214 ReturnValue { kind, label_ops }
215 }
216}
217
218impl fmt::Display for Selector {
219 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
220 if let Some(metric) = &self.metric {
221 write!(f, "{}", metric)?;
222 }
223
224 if !self.labels.is_empty() {
225 write!(f, "{{")?;
226 for (i, label) in self.labels.iter().enumerate() {
227 if i > 0 {
228 write!(f, ",")?;
229 }
230
231 write!(f, "{}", label)?;
232 }
233
234 write!(f, "}}")?;
235 };
236
237 if let Some(range) = &self.range {
238 write!(f, "[{}]", range)?;
239 }
240
241 if let Some(offset) = &self.offset {
242 write!(f, " offset {}", offset)?;
243 }
244
245 if let Some(subquery) = &self.subquery {
246 write!(f, "{}", subquery)?;
247 }
248
249 Ok(())
250 }
251}