1use std::collections::{HashMap, HashSet};
16use std::fmt;
17
18use lazy_static::lazy_static;
19
20use crate::parser::value::ValueType;
21use crate::parser::{Expr, Prettier};
22use crate::util::join_vector;
23
24#[derive(Debug, Clone, PartialEq, Eq)]
26#[cfg_attr(feature = "ser", derive(serde::Serialize))]
27pub struct FunctionArgs {
28 pub args: Vec<Box<Expr>>,
29}
30
31impl FunctionArgs {
32 pub fn empty_args() -> Self {
33 Self { args: vec![] }
34 }
35
36 pub fn new_args(expr: Expr) -> Self {
37 Self {
38 args: vec![Box::new(expr)],
39 }
40 }
41
42 pub fn append_args(mut self: FunctionArgs, expr: Expr) -> Self {
43 self.args.push(Box::new(expr));
44 self
45 }
46
47 pub fn is_empty(&self) -> bool {
48 self.args.is_empty()
49 }
50
51 pub fn len(&self) -> usize {
52 self.args.len()
53 }
54
55 pub fn first(&self) -> Option<Box<Expr>> {
56 self.args.first().cloned()
57 }
58
59 pub fn last(&self) -> Option<Box<Expr>> {
60 self.args.last().cloned()
61 }
62}
63
64impl fmt::Display for FunctionArgs {
65 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
66 write!(f, "{}", join_vector(&self.args, ", ", false))
67 }
68}
69
70impl Prettier for FunctionArgs {
71 fn pretty(&self, level: usize, max: usize) -> String {
72 let mut v = vec![];
73 for ex in &self.args {
74 v.push(ex.pretty(level, max));
75 }
76 v.join(",\n")
77 }
78}
79
80#[derive(Debug, Clone, PartialEq, Eq)]
82#[cfg_attr(feature = "ser", derive(serde::Serialize))]
83#[cfg_attr(feature = "ser", serde(rename_all = "camelCase"))]
84pub struct Function {
85 pub name: &'static str,
86 pub arg_types: Vec<ValueType>,
87 #[cfg_attr(
88 feature = "ser",
89 serde(serialize_with = "Function::serialize_variadic")
90 )]
91 pub variadic: bool,
92 pub return_type: ValueType,
93}
94
95impl Function {
96 pub fn new(
97 name: &'static str,
98 arg_types: Vec<ValueType>,
99 variadic: bool,
100 return_type: ValueType,
101 ) -> Self {
102 Self {
103 name,
104 arg_types,
105 variadic,
106 return_type,
107 }
108 }
109
110 #[cfg(feature = "ser")]
111 pub(crate) fn serialize_variadic<S>(variadic: &bool, serializer: S) -> Result<S::Ok, S::Error>
112 where
113 S: serde::Serializer,
114 {
115 if *variadic {
116 serializer.serialize_i8(1)
117 } else {
118 serializer.serialize_i8(0)
119 }
120 }
121}
122
123macro_rules! map {
124 ($(($name:literal, $arg:expr, $ret:expr)),*) => (
126 {
127 let mut m: HashMap<&'static str, Function> = HashMap::new();
128 $(
129 let variadic = FUNCTIONS_WITH_VARIADIC_ARGS.contains($name);
130 let func = Function::new($name, $arg, variadic, $ret);
131 m.insert($name, func);
132 )*
133 m
134 }
135 );
136}
137
138lazy_static! {
139 static ref FUNCTIONS_WITH_VARIADIC_ARGS: HashSet<&'static str> = HashSet::from([
140 "days_in_month",
141 "day_of_year",
142 "day_of_month",
143 "day_of_week",
144 "year",
145 "month",
146 "hour",
147 "minute",
148 "label_join",
149 "sort_by_label",
150 "sort_by_label_desc",
151 "round",
152 ]);
153 static ref FUNCTIONS: HashMap<&'static str, Function> = map!(
154 ("abs", vec![ValueType::Vector], ValueType::Vector),
155 ("absent", vec![ValueType::Vector], ValueType::Vector),
156 (
157 "absent_over_time",
158 vec![ValueType::Matrix],
159 ValueType::Vector
160 ),
161 ("acos", vec![ValueType::Vector], ValueType::Vector),
162 ("acosh", vec![ValueType::Vector], ValueType::Vector),
163 ("asin", vec![ValueType::Vector], ValueType::Vector),
164 ("asinh", vec![ValueType::Vector], ValueType::Vector),
165 ("atan", vec![ValueType::Vector], ValueType::Vector),
166 ("atanh", vec![ValueType::Vector], ValueType::Vector),
167 ("avg_over_time", vec![ValueType::Matrix], ValueType::Vector),
168 ("ceil", vec![ValueType::Vector], ValueType::Vector),
169 ("changes", vec![ValueType::Matrix], ValueType::Vector),
170 (
171 "clamp",
172 vec![ValueType::Vector, ValueType::Scalar, ValueType::Scalar],
173 ValueType::Vector
174 ),
175 (
176 "clamp_max",
177 vec![ValueType::Vector, ValueType::Scalar],
178 ValueType::Vector
179 ),
180 (
181 "clamp_min",
182 vec![ValueType::Vector, ValueType::Scalar],
183 ValueType::Vector
184 ),
185 ("cos", vec![ValueType::Vector], ValueType::Vector),
186 ("cosh", vec![ValueType::Vector], ValueType::Vector),
187 (
188 "count_over_time",
189 vec![ValueType::Matrix],
190 ValueType::Vector
191 ),
192 ("days_in_month", vec![ValueType::Vector], ValueType::Vector),
193 ("day_of_month", vec![ValueType::Vector], ValueType::Vector),
194 ("day_of_week", vec![ValueType::Vector], ValueType::Vector),
195 ("day_of_year", vec![ValueType::Vector], ValueType::Vector),
196 ("deg", vec![ValueType::Vector], ValueType::Vector),
197 ("delta", vec![ValueType::Matrix], ValueType::Vector),
198 ("deriv", vec![ValueType::Matrix], ValueType::Vector),
199 ("exp", vec![ValueType::Vector], ValueType::Vector),
200 ("floor", vec![ValueType::Vector], ValueType::Vector),
201 (
202 "histogram_count",
203 vec![ValueType::Vector],
204 ValueType::Vector
205 ),
206 ("histogram_sum", vec![ValueType::Vector], ValueType::Vector),
207 (
208 "histogram_fraction",
209 vec![ValueType::Scalar, ValueType::Scalar, ValueType::Vector],
210 ValueType::Vector
211 ),
212 (
213 "histogram_quantile",
214 vec![ValueType::Scalar, ValueType::Vector],
215 ValueType::Vector
216 ),
217 (
218 "holt_winters",
219 vec![ValueType::Matrix, ValueType::Scalar, ValueType::Scalar],
220 ValueType::Vector
221 ),
222 ("hour", vec![ValueType::Vector], ValueType::Vector),
223 ("idelta", vec![ValueType::Matrix], ValueType::Vector),
224 ("increase", vec![ValueType::Matrix], ValueType::Vector),
225 ("irate", vec![ValueType::Matrix], ValueType::Vector),
226 (
227 "label_replace",
228 vec![
229 ValueType::Vector,
230 ValueType::String,
231 ValueType::String,
232 ValueType::String,
233 ValueType::String,
234 ],
235 ValueType::Vector
236 ),
237 (
238 "label_join",
239 vec![
240 ValueType::Vector,
241 ValueType::String,
242 ValueType::String,
243 ValueType::String,
244 ],
245 ValueType::Vector
246 ),
247 ("last_over_time", vec![ValueType::Matrix], ValueType::Vector),
248 ("ln", vec![ValueType::Vector], ValueType::Vector),
249 ("log10", vec![ValueType::Vector], ValueType::Vector),
250 ("log2", vec![ValueType::Vector], ValueType::Vector),
251 ("max_over_time", vec![ValueType::Matrix], ValueType::Vector),
252 ("min_over_time", vec![ValueType::Matrix], ValueType::Vector),
253 ("minute", vec![ValueType::Vector], ValueType::Vector),
254 ("month", vec![ValueType::Vector], ValueType::Vector),
255 ("pi", vec![], ValueType::Scalar),
256 (
257 "predict_linear",
258 vec![ValueType::Matrix, ValueType::Scalar],
259 ValueType::Vector
260 ),
261 (
262 "present_over_time",
263 vec![ValueType::Matrix],
264 ValueType::Vector
265 ),
266 (
267 "quantile_over_time",
268 vec![ValueType::Scalar, ValueType::Matrix],
269 ValueType::Vector
270 ),
271 ("rad", vec![ValueType::Vector], ValueType::Vector),
272 ("rate", vec![ValueType::Matrix], ValueType::Vector),
273 ("resets", vec![ValueType::Matrix], ValueType::Vector),
274 (
275 "round",
276 vec![ValueType::Vector, ValueType::Scalar],
277 ValueType::Vector
278 ),
279 ("scalar", vec![ValueType::Vector], ValueType::Scalar),
280 ("sgn", vec![ValueType::Vector], ValueType::Vector),
281 ("sin", vec![ValueType::Vector], ValueType::Vector),
282 ("sinh", vec![ValueType::Vector], ValueType::Vector),
283 ("sort", vec![ValueType::Vector], ValueType::Vector),
284 ("sort_desc", vec![ValueType::Vector], ValueType::Vector),
285 (
286 "sort_by_label",
287 vec![ValueType::Vector, ValueType::String, ValueType::String],
288 ValueType::Vector
289 ),
290 (
291 "sort_by_label_desc",
292 vec![ValueType::Vector, ValueType::String, ValueType::String],
293 ValueType::Vector
294 ),
295 ("sqrt", vec![ValueType::Vector], ValueType::Vector),
296 (
297 "stddev_over_time",
298 vec![ValueType::Matrix],
299 ValueType::Vector
300 ),
301 (
302 "stdvar_over_time",
303 vec![ValueType::Matrix],
304 ValueType::Vector
305 ),
306 ("sum_over_time", vec![ValueType::Matrix], ValueType::Vector),
307 ("tan", vec![ValueType::Vector], ValueType::Vector),
308 ("tanh", vec![ValueType::Vector], ValueType::Vector),
309 ("time", vec![], ValueType::Scalar),
310 ("timestamp", vec![ValueType::Vector], ValueType::Vector),
311 ("vector", vec![ValueType::Scalar], ValueType::Vector),
312 ("year", vec![ValueType::Vector], ValueType::Vector)
313 );
314}
315
316pub(crate) fn get_function(name: &str) -> Option<Function> {
318 FUNCTIONS.get(name).cloned()
319}
320
321#[cfg(test)]
322mod tests {
323 use super::*;
324 use crate::parser::*;
325
326 #[test]
327 fn test_function_equality() {
328 let func = "month";
329 assert!(get_function(func).is_some());
330 assert_eq!(get_function(func), get_function(func));
331 }
332
333 #[test]
334 fn test_function_args_equality() {
335 assert_eq!(FunctionArgs::empty_args(), FunctionArgs::empty_args());
336
337 let arg1 = Expr::NumberLiteral(NumberLiteral::new(1.0));
338 let arg2 = Expr::StringLiteral(StringLiteral {
339 val: "prometheus".into(),
340 });
341 let args1 = FunctionArgs::new_args(arg1).append_args(arg2);
342
343 let arg1 = Expr::NumberLiteral(NumberLiteral::new(0.5 + 0.5));
344 let arg2 = Expr::StringLiteral(StringLiteral {
345 val: String::from("prometheus"),
346 });
347 let args2 = FunctionArgs::new_args(arg1).append_args(arg2);
348
349 assert_eq!(args1, args2);
350 }
351
352 #[test]
353 fn test_args_display() {
354 let cases = vec![
355 (
356 FunctionArgs::new_args(Expr::from(VectorSelector::from("up"))),
357 "up",
358 ),
359 (
360 FunctionArgs::empty_args()
361 .append_args(Expr::from("src1"))
362 .append_args(Expr::from("src2"))
363 .append_args(Expr::from("src3")),
364 r#""src1", "src2", "src3""#,
365 ),
366 ];
367
368 for (args, expect) in cases {
369 assert_eq!(expect, args.to_string())
370 }
371 }
372}