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 ("histogram_avg", vec![ValueType::Vector], ValueType::Vector),
208 (
209 "histogram_fraction",
210 vec![ValueType::Scalar, ValueType::Scalar, ValueType::Vector],
211 ValueType::Vector
212 ),
213 (
214 "histogram_quantile",
215 vec![ValueType::Scalar, ValueType::Vector],
216 ValueType::Vector
217 ),
218 (
219 "holt_winters",
220 vec![ValueType::Matrix, ValueType::Scalar, ValueType::Scalar],
221 ValueType::Vector
222 ),
223 ("hour", vec![ValueType::Vector], ValueType::Vector),
224 ("idelta", vec![ValueType::Matrix], ValueType::Vector),
225 ("increase", vec![ValueType::Matrix], ValueType::Vector),
226 ("irate", vec![ValueType::Matrix], ValueType::Vector),
227 (
228 "label_replace",
229 vec![
230 ValueType::Vector,
231 ValueType::String,
232 ValueType::String,
233 ValueType::String,
234 ValueType::String,
235 ],
236 ValueType::Vector
237 ),
238 (
239 "label_join",
240 vec![
241 ValueType::Vector,
242 ValueType::String,
243 ValueType::String,
244 ValueType::String,
245 ],
246 ValueType::Vector
247 ),
248 ("last_over_time", vec![ValueType::Matrix], ValueType::Vector),
249 ("ln", vec![ValueType::Vector], ValueType::Vector),
250 ("log10", vec![ValueType::Vector], ValueType::Vector),
251 ("log2", vec![ValueType::Vector], ValueType::Vector),
252 ("max_over_time", vec![ValueType::Matrix], ValueType::Vector),
253 ("min_over_time", vec![ValueType::Matrix], ValueType::Vector),
254 ("minute", vec![ValueType::Vector], ValueType::Vector),
255 ("month", vec![ValueType::Vector], ValueType::Vector),
256 ("pi", vec![], ValueType::Scalar),
257 (
258 "predict_linear",
259 vec![ValueType::Matrix, ValueType::Scalar],
260 ValueType::Vector
261 ),
262 (
263 "present_over_time",
264 vec![ValueType::Matrix],
265 ValueType::Vector
266 ),
267 (
268 "quantile_over_time",
269 vec![ValueType::Scalar, ValueType::Matrix],
270 ValueType::Vector
271 ),
272 ("rad", vec![ValueType::Vector], ValueType::Vector),
273 ("rate", vec![ValueType::Matrix], ValueType::Vector),
274 ("resets", vec![ValueType::Matrix], ValueType::Vector),
275 (
276 "round",
277 vec![ValueType::Vector, ValueType::Scalar],
278 ValueType::Vector
279 ),
280 ("scalar", vec![ValueType::Vector], ValueType::Scalar),
281 ("sgn", vec![ValueType::Vector], ValueType::Vector),
282 ("sin", vec![ValueType::Vector], ValueType::Vector),
283 ("sinh", vec![ValueType::Vector], ValueType::Vector),
284 ("sort", vec![ValueType::Vector], ValueType::Vector),
285 ("sort_desc", vec![ValueType::Vector], ValueType::Vector),
286 (
287 "sort_by_label",
288 vec![ValueType::Vector, ValueType::String, ValueType::String],
289 ValueType::Vector
290 ),
291 (
292 "sort_by_label_desc",
293 vec![ValueType::Vector, ValueType::String, ValueType::String],
294 ValueType::Vector
295 ),
296 ("sqrt", vec![ValueType::Vector], ValueType::Vector),
297 (
298 "stddev_over_time",
299 vec![ValueType::Matrix],
300 ValueType::Vector
301 ),
302 (
303 "stdvar_over_time",
304 vec![ValueType::Matrix],
305 ValueType::Vector
306 ),
307 ("sum_over_time", vec![ValueType::Matrix], ValueType::Vector),
308 ("tan", vec![ValueType::Vector], ValueType::Vector),
309 ("tanh", vec![ValueType::Vector], ValueType::Vector),
310 ("time", vec![], ValueType::Scalar),
311 ("timestamp", vec![ValueType::Vector], ValueType::Vector),
312 ("vector", vec![ValueType::Scalar], ValueType::Vector),
313 ("year", vec![ValueType::Vector], ValueType::Vector)
314 );
315}
316
317pub(crate) fn get_function(name: &str) -> Option<Function> {
319 FUNCTIONS.get(name).cloned()
320}
321
322#[cfg(test)]
323mod tests {
324 use super::*;
325 use crate::parser::*;
326
327 #[test]
328 fn test_function_equality() {
329 let func = "month";
330 assert!(get_function(func).is_some());
331 assert_eq!(get_function(func), get_function(func));
332 }
333
334 #[test]
335 fn test_function_args_equality() {
336 assert_eq!(FunctionArgs::empty_args(), FunctionArgs::empty_args());
337
338 let arg1 = Expr::NumberLiteral(NumberLiteral::new(1.0));
339 let arg2 = Expr::StringLiteral(StringLiteral {
340 val: "prometheus".into(),
341 });
342 let args1 = FunctionArgs::new_args(arg1).append_args(arg2);
343
344 let arg1 = Expr::NumberLiteral(NumberLiteral::new(0.5 + 0.5));
345 let arg2 = Expr::StringLiteral(StringLiteral {
346 val: String::from("prometheus"),
347 });
348 let args2 = FunctionArgs::new_args(arg1).append_args(arg2);
349
350 assert_eq!(args1, args2);
351 }
352
353 #[test]
354 fn test_args_display() {
355 let cases = vec![
356 (
357 FunctionArgs::new_args(Expr::from(VectorSelector::from("up"))),
358 "up",
359 ),
360 (
361 FunctionArgs::empty_args()
362 .append_args(Expr::from("src1"))
363 .append_args(Expr::from("src2"))
364 .append_args(Expr::from("src3")),
365 r#""src1", "src2", "src3""#,
366 ),
367 ];
368
369 for (args, expect) in cases {
370 assert_eq!(expect, args.to_string())
371 }
372 }
373}