rusty_promql_parser/parser/
function.rs

1//! Built-in PromQL function definitions.
2//!
3//! This module defines the signatures of all built-in PromQL functions.
4//! It can be used for validation and documentation purposes.
5//!
6//! # Function Categories
7//!
8//! - **Math functions**: `abs`, `ceil`, `floor`, `exp`, `sqrt`, `ln`, `log2`, `log10`
9//! - **Trigonometric**: `acos`, `asin`, `atan`, `cos`, `sin`, `tan` (and hyperbolic variants)
10//! - **Rounding/clamping**: `round`, `clamp`, `clamp_min`, `clamp_max`
11//! - **Sorting**: `sort`, `sort_desc`, `sort_by_label`
12//! - **Rate functions**: `rate`, `irate`, `increase`, `delta`, `idelta`, `deriv`
13//! - **Aggregation over time**: `avg_over_time`, `sum_over_time`, `min_over_time`, etc.
14//! - **Time functions**: `time`, `timestamp`, `hour`, `minute`, `month`, `year`
15//! - **Label functions**: `label_replace`, `label_join`
16//! - **Histogram functions**: `histogram_quantile`, `histogram_avg`, `histogram_count`
17//!
18//! # Example
19//!
20//! ```rust
21//! use rusty_promql_parser::parser::function::{get_function, is_function};
22//!
23//! assert!(is_function("rate"));
24//! assert!(!is_function("unknown_func"));
25//!
26//! let func = get_function("rate").unwrap();
27//! assert_eq!(func.name, "rate");
28//! assert_eq!(func.min_args(), 1);
29//! ```
30
31/// Value types for function arguments and return values.
32///
33/// PromQL has four fundamental value types that functions operate on.
34#[derive(Debug, Clone, Copy, PartialEq, Eq)]
35pub enum ValueType {
36    /// Scalar value (single number).
37    Scalar,
38    /// Instant vector (set of time series with single sample each).
39    Vector,
40    /// Range vector (set of time series with samples over time range).
41    Matrix,
42    /// String value.
43    String,
44}
45
46impl std::fmt::Display for ValueType {
47    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
48        match self {
49            ValueType::Scalar => write!(f, "scalar"),
50            ValueType::Vector => write!(f, "instant vector"),
51            ValueType::Matrix => write!(f, "range vector"),
52            ValueType::String => write!(f, "string"),
53        }
54    }
55}
56
57/// Variadic argument specification.
58///
59/// Determines how many arguments a function accepts beyond the required ones.
60#[derive(Debug, Clone, Copy, PartialEq, Eq)]
61pub enum Variadic {
62    /// Fixed number of arguments (only those specified in `arg_types`).
63    None,
64    /// Last argument type can repeat indefinitely.
65    Repeat,
66    /// Optional trailing arguments (number indicates how many of `arg_types` are optional).
67    Optional(u8),
68}
69
70/// Function signature definition.
71///
72/// Describes the name, argument types, return type, and variadic behavior
73/// of a built-in PromQL function.
74#[derive(Debug, Clone)]
75pub struct Function {
76    /// Function name.
77    pub name: &'static str,
78    /// Argument types (in order).
79    pub arg_types: &'static [ValueType],
80    /// Variadic specification.
81    pub variadic: Variadic,
82    /// Return type.
83    pub return_type: ValueType,
84    /// Whether this is an experimental function.
85    pub experimental: bool,
86}
87
88impl Function {
89    /// Get the minimum number of arguments.
90    ///
91    /// - For `Variadic::Repeat`: `arg_types.len() - 1`
92    /// - For `Variadic::Optional(n)`: `arg_types.len() - n`
93    /// - For `Variadic::None`: `arg_types.len()`
94    pub fn min_args(&self) -> usize {
95        match self.variadic {
96            Variadic::None => self.arg_types.len(),
97            Variadic::Repeat => self.arg_types.len().saturating_sub(1),
98            Variadic::Optional(n) => self.arg_types.len().saturating_sub(n as usize),
99        }
100    }
101
102    /// Get the maximum number of arguments.
103    ///
104    /// Returns `None` for variadic functions that accept unlimited arguments.
105    pub fn max_args(&self) -> Option<usize> {
106        match self.variadic {
107            Variadic::None => Some(self.arg_types.len()),
108            Variadic::Repeat => None, // Unlimited
109            Variadic::Optional(_) => Some(self.arg_types.len()),
110        }
111    }
112}
113
114/// All built-in PromQL functions.
115///
116/// This static array contains the definitions of all standard PromQL functions
117/// as defined in the Prometheus documentation.
118pub static FUNCTIONS: &[Function] = &[
119    // Math functions
120    Function {
121        name: "abs",
122        arg_types: &[ValueType::Vector],
123        variadic: Variadic::None,
124        return_type: ValueType::Vector,
125        experimental: false,
126    },
127    Function {
128        name: "ceil",
129        arg_types: &[ValueType::Vector],
130        variadic: Variadic::None,
131        return_type: ValueType::Vector,
132        experimental: false,
133    },
134    Function {
135        name: "floor",
136        arg_types: &[ValueType::Vector],
137        variadic: Variadic::None,
138        return_type: ValueType::Vector,
139        experimental: false,
140    },
141    Function {
142        name: "exp",
143        arg_types: &[ValueType::Vector],
144        variadic: Variadic::None,
145        return_type: ValueType::Vector,
146        experimental: false,
147    },
148    Function {
149        name: "sqrt",
150        arg_types: &[ValueType::Vector],
151        variadic: Variadic::None,
152        return_type: ValueType::Vector,
153        experimental: false,
154    },
155    Function {
156        name: "ln",
157        arg_types: &[ValueType::Vector],
158        variadic: Variadic::None,
159        return_type: ValueType::Vector,
160        experimental: false,
161    },
162    Function {
163        name: "log2",
164        arg_types: &[ValueType::Vector],
165        variadic: Variadic::None,
166        return_type: ValueType::Vector,
167        experimental: false,
168    },
169    Function {
170        name: "log10",
171        arg_types: &[ValueType::Vector],
172        variadic: Variadic::None,
173        return_type: ValueType::Vector,
174        experimental: false,
175    },
176    Function {
177        name: "sgn",
178        arg_types: &[ValueType::Vector],
179        variadic: Variadic::None,
180        return_type: ValueType::Vector,
181        experimental: false,
182    },
183    Function {
184        name: "deg",
185        arg_types: &[ValueType::Vector],
186        variadic: Variadic::None,
187        return_type: ValueType::Vector,
188        experimental: false,
189    },
190    Function {
191        name: "rad",
192        arg_types: &[ValueType::Vector],
193        variadic: Variadic::None,
194        return_type: ValueType::Vector,
195        experimental: false,
196    },
197    // Trigonometric functions
198    Function {
199        name: "acos",
200        arg_types: &[ValueType::Vector],
201        variadic: Variadic::None,
202        return_type: ValueType::Vector,
203        experimental: false,
204    },
205    Function {
206        name: "acosh",
207        arg_types: &[ValueType::Vector],
208        variadic: Variadic::None,
209        return_type: ValueType::Vector,
210        experimental: false,
211    },
212    Function {
213        name: "asin",
214        arg_types: &[ValueType::Vector],
215        variadic: Variadic::None,
216        return_type: ValueType::Vector,
217        experimental: false,
218    },
219    Function {
220        name: "asinh",
221        arg_types: &[ValueType::Vector],
222        variadic: Variadic::None,
223        return_type: ValueType::Vector,
224        experimental: false,
225    },
226    Function {
227        name: "atan",
228        arg_types: &[ValueType::Vector],
229        variadic: Variadic::None,
230        return_type: ValueType::Vector,
231        experimental: false,
232    },
233    Function {
234        name: "atanh",
235        arg_types: &[ValueType::Vector],
236        variadic: Variadic::None,
237        return_type: ValueType::Vector,
238        experimental: false,
239    },
240    Function {
241        name: "cos",
242        arg_types: &[ValueType::Vector],
243        variadic: Variadic::None,
244        return_type: ValueType::Vector,
245        experimental: false,
246    },
247    Function {
248        name: "cosh",
249        arg_types: &[ValueType::Vector],
250        variadic: Variadic::None,
251        return_type: ValueType::Vector,
252        experimental: false,
253    },
254    Function {
255        name: "sin",
256        arg_types: &[ValueType::Vector],
257        variadic: Variadic::None,
258        return_type: ValueType::Vector,
259        experimental: false,
260    },
261    Function {
262        name: "sinh",
263        arg_types: &[ValueType::Vector],
264        variadic: Variadic::None,
265        return_type: ValueType::Vector,
266        experimental: false,
267    },
268    Function {
269        name: "tan",
270        arg_types: &[ValueType::Vector],
271        variadic: Variadic::None,
272        return_type: ValueType::Vector,
273        experimental: false,
274    },
275    Function {
276        name: "tanh",
277        arg_types: &[ValueType::Vector],
278        variadic: Variadic::None,
279        return_type: ValueType::Vector,
280        experimental: false,
281    },
282    // Rounding/clamping functions
283    Function {
284        name: "round",
285        arg_types: &[ValueType::Vector, ValueType::Scalar],
286        variadic: Variadic::Optional(1),
287        return_type: ValueType::Vector,
288        experimental: false,
289    },
290    Function {
291        name: "clamp",
292        arg_types: &[ValueType::Vector, ValueType::Scalar, ValueType::Scalar],
293        variadic: Variadic::None,
294        return_type: ValueType::Vector,
295        experimental: false,
296    },
297    Function {
298        name: "clamp_min",
299        arg_types: &[ValueType::Vector, ValueType::Scalar],
300        variadic: Variadic::None,
301        return_type: ValueType::Vector,
302        experimental: false,
303    },
304    Function {
305        name: "clamp_max",
306        arg_types: &[ValueType::Vector, ValueType::Scalar],
307        variadic: Variadic::None,
308        return_type: ValueType::Vector,
309        experimental: false,
310    },
311    // Sorting functions
312    Function {
313        name: "sort",
314        arg_types: &[ValueType::Vector],
315        variadic: Variadic::None,
316        return_type: ValueType::Vector,
317        experimental: false,
318    },
319    Function {
320        name: "sort_desc",
321        arg_types: &[ValueType::Vector],
322        variadic: Variadic::None,
323        return_type: ValueType::Vector,
324        experimental: false,
325    },
326    Function {
327        name: "sort_by_label",
328        arg_types: &[ValueType::Vector, ValueType::String],
329        variadic: Variadic::Repeat,
330        return_type: ValueType::Vector,
331        experimental: true,
332    },
333    Function {
334        name: "sort_by_label_desc",
335        arg_types: &[ValueType::Vector, ValueType::String],
336        variadic: Variadic::Repeat,
337        return_type: ValueType::Vector,
338        experimental: true,
339    },
340    // Rate/counter functions (range vector -> instant vector)
341    Function {
342        name: "rate",
343        arg_types: &[ValueType::Matrix],
344        variadic: Variadic::None,
345        return_type: ValueType::Vector,
346        experimental: false,
347    },
348    Function {
349        name: "irate",
350        arg_types: &[ValueType::Matrix],
351        variadic: Variadic::None,
352        return_type: ValueType::Vector,
353        experimental: false,
354    },
355    Function {
356        name: "increase",
357        arg_types: &[ValueType::Matrix],
358        variadic: Variadic::None,
359        return_type: ValueType::Vector,
360        experimental: false,
361    },
362    Function {
363        name: "delta",
364        arg_types: &[ValueType::Matrix],
365        variadic: Variadic::None,
366        return_type: ValueType::Vector,
367        experimental: false,
368    },
369    Function {
370        name: "idelta",
371        arg_types: &[ValueType::Matrix],
372        variadic: Variadic::None,
373        return_type: ValueType::Vector,
374        experimental: false,
375    },
376    Function {
377        name: "deriv",
378        arg_types: &[ValueType::Matrix],
379        variadic: Variadic::None,
380        return_type: ValueType::Vector,
381        experimental: false,
382    },
383    Function {
384        name: "changes",
385        arg_types: &[ValueType::Matrix],
386        variadic: Variadic::None,
387        return_type: ValueType::Vector,
388        experimental: false,
389    },
390    Function {
391        name: "resets",
392        arg_types: &[ValueType::Matrix],
393        variadic: Variadic::None,
394        return_type: ValueType::Vector,
395        experimental: false,
396    },
397    // Over-time aggregation functions (range vector -> instant vector)
398    Function {
399        name: "avg_over_time",
400        arg_types: &[ValueType::Matrix],
401        variadic: Variadic::None,
402        return_type: ValueType::Vector,
403        experimental: false,
404    },
405    Function {
406        name: "sum_over_time",
407        arg_types: &[ValueType::Matrix],
408        variadic: Variadic::None,
409        return_type: ValueType::Vector,
410        experimental: false,
411    },
412    Function {
413        name: "count_over_time",
414        arg_types: &[ValueType::Matrix],
415        variadic: Variadic::None,
416        return_type: ValueType::Vector,
417        experimental: false,
418    },
419    Function {
420        name: "min_over_time",
421        arg_types: &[ValueType::Matrix],
422        variadic: Variadic::None,
423        return_type: ValueType::Vector,
424        experimental: false,
425    },
426    Function {
427        name: "max_over_time",
428        arg_types: &[ValueType::Matrix],
429        variadic: Variadic::None,
430        return_type: ValueType::Vector,
431        experimental: false,
432    },
433    Function {
434        name: "stddev_over_time",
435        arg_types: &[ValueType::Matrix],
436        variadic: Variadic::None,
437        return_type: ValueType::Vector,
438        experimental: false,
439    },
440    Function {
441        name: "stdvar_over_time",
442        arg_types: &[ValueType::Matrix],
443        variadic: Variadic::None,
444        return_type: ValueType::Vector,
445        experimental: false,
446    },
447    Function {
448        name: "last_over_time",
449        arg_types: &[ValueType::Matrix],
450        variadic: Variadic::None,
451        return_type: ValueType::Vector,
452        experimental: false,
453    },
454    Function {
455        name: "first_over_time",
456        arg_types: &[ValueType::Matrix],
457        variadic: Variadic::None,
458        return_type: ValueType::Vector,
459        experimental: true,
460    },
461    Function {
462        name: "present_over_time",
463        arg_types: &[ValueType::Matrix],
464        variadic: Variadic::None,
465        return_type: ValueType::Vector,
466        experimental: false,
467    },
468    Function {
469        name: "absent_over_time",
470        arg_types: &[ValueType::Matrix],
471        variadic: Variadic::None,
472        return_type: ValueType::Vector,
473        experimental: false,
474    },
475    Function {
476        name: "quantile_over_time",
477        arg_types: &[ValueType::Scalar, ValueType::Matrix],
478        variadic: Variadic::None,
479        return_type: ValueType::Vector,
480        experimental: false,
481    },
482    Function {
483        name: "mad_over_time",
484        arg_types: &[ValueType::Matrix],
485        variadic: Variadic::None,
486        return_type: ValueType::Vector,
487        experimental: true,
488    },
489    // Timestamp functions
490    Function {
491        name: "ts_of_first_over_time",
492        arg_types: &[ValueType::Matrix],
493        variadic: Variadic::None,
494        return_type: ValueType::Vector,
495        experimental: true,
496    },
497    Function {
498        name: "ts_of_max_over_time",
499        arg_types: &[ValueType::Matrix],
500        variadic: Variadic::None,
501        return_type: ValueType::Vector,
502        experimental: true,
503    },
504    Function {
505        name: "ts_of_min_over_time",
506        arg_types: &[ValueType::Matrix],
507        variadic: Variadic::None,
508        return_type: ValueType::Vector,
509        experimental: true,
510    },
511    Function {
512        name: "ts_of_last_over_time",
513        arg_types: &[ValueType::Matrix],
514        variadic: Variadic::None,
515        return_type: ValueType::Vector,
516        experimental: true,
517    },
518    // Time functions
519    Function {
520        name: "time",
521        arg_types: &[],
522        variadic: Variadic::None,
523        return_type: ValueType::Scalar,
524        experimental: false,
525    },
526    Function {
527        name: "timestamp",
528        arg_types: &[ValueType::Vector],
529        variadic: Variadic::None,
530        return_type: ValueType::Vector,
531        experimental: false,
532    },
533    Function {
534        name: "hour",
535        arg_types: &[ValueType::Vector],
536        variadic: Variadic::Optional(1),
537        return_type: ValueType::Vector,
538        experimental: false,
539    },
540    Function {
541        name: "minute",
542        arg_types: &[ValueType::Vector],
543        variadic: Variadic::Optional(1),
544        return_type: ValueType::Vector,
545        experimental: false,
546    },
547    Function {
548        name: "month",
549        arg_types: &[ValueType::Vector],
550        variadic: Variadic::Optional(1),
551        return_type: ValueType::Vector,
552        experimental: false,
553    },
554    Function {
555        name: "year",
556        arg_types: &[ValueType::Vector],
557        variadic: Variadic::Optional(1),
558        return_type: ValueType::Vector,
559        experimental: false,
560    },
561    Function {
562        name: "day_of_week",
563        arg_types: &[ValueType::Vector],
564        variadic: Variadic::Optional(1),
565        return_type: ValueType::Vector,
566        experimental: false,
567    },
568    Function {
569        name: "day_of_month",
570        arg_types: &[ValueType::Vector],
571        variadic: Variadic::Optional(1),
572        return_type: ValueType::Vector,
573        experimental: false,
574    },
575    Function {
576        name: "day_of_year",
577        arg_types: &[ValueType::Vector],
578        variadic: Variadic::Optional(1),
579        return_type: ValueType::Vector,
580        experimental: false,
581    },
582    Function {
583        name: "days_in_month",
584        arg_types: &[ValueType::Vector],
585        variadic: Variadic::Optional(1),
586        return_type: ValueType::Vector,
587        experimental: false,
588    },
589    // Label functions
590    Function {
591        name: "label_replace",
592        arg_types: &[
593            ValueType::Vector,
594            ValueType::String,
595            ValueType::String,
596            ValueType::String,
597            ValueType::String,
598        ],
599        variadic: Variadic::None,
600        return_type: ValueType::Vector,
601        experimental: false,
602    },
603    Function {
604        name: "label_join",
605        arg_types: &[
606            ValueType::Vector,
607            ValueType::String,
608            ValueType::String,
609            ValueType::String,
610        ],
611        variadic: Variadic::Repeat,
612        return_type: ValueType::Vector,
613        experimental: false,
614    },
615    // Other functions
616    Function {
617        name: "absent",
618        arg_types: &[ValueType::Vector],
619        variadic: Variadic::None,
620        return_type: ValueType::Vector,
621        experimental: false,
622    },
623    Function {
624        name: "scalar",
625        arg_types: &[ValueType::Vector],
626        variadic: Variadic::None,
627        return_type: ValueType::Scalar,
628        experimental: false,
629    },
630    Function {
631        name: "vector",
632        arg_types: &[ValueType::Scalar],
633        variadic: Variadic::None,
634        return_type: ValueType::Vector,
635        experimental: false,
636    },
637    Function {
638        name: "predict_linear",
639        arg_types: &[ValueType::Matrix, ValueType::Scalar],
640        variadic: Variadic::None,
641        return_type: ValueType::Vector,
642        experimental: false,
643    },
644    Function {
645        name: "pi",
646        arg_types: &[],
647        variadic: Variadic::None,
648        return_type: ValueType::Scalar,
649        experimental: false,
650    },
651    // Histogram functions
652    Function {
653        name: "histogram_quantile",
654        arg_types: &[ValueType::Scalar, ValueType::Vector],
655        variadic: Variadic::None,
656        return_type: ValueType::Vector,
657        experimental: false,
658    },
659    Function {
660        name: "histogram_avg",
661        arg_types: &[ValueType::Vector],
662        variadic: Variadic::None,
663        return_type: ValueType::Vector,
664        experimental: false,
665    },
666    Function {
667        name: "histogram_count",
668        arg_types: &[ValueType::Vector],
669        variadic: Variadic::None,
670        return_type: ValueType::Vector,
671        experimental: false,
672    },
673    Function {
674        name: "histogram_sum",
675        arg_types: &[ValueType::Vector],
676        variadic: Variadic::None,
677        return_type: ValueType::Vector,
678        experimental: false,
679    },
680    Function {
681        name: "histogram_stddev",
682        arg_types: &[ValueType::Vector],
683        variadic: Variadic::None,
684        return_type: ValueType::Vector,
685        experimental: false,
686    },
687    Function {
688        name: "histogram_stdvar",
689        arg_types: &[ValueType::Vector],
690        variadic: Variadic::None,
691        return_type: ValueType::Vector,
692        experimental: false,
693    },
694    Function {
695        name: "histogram_fraction",
696        arg_types: &[ValueType::Scalar, ValueType::Scalar, ValueType::Vector],
697        variadic: Variadic::None,
698        return_type: ValueType::Vector,
699        experimental: false,
700    },
701    Function {
702        name: "double_exponential_smoothing",
703        arg_types: &[ValueType::Matrix, ValueType::Scalar, ValueType::Scalar],
704        variadic: Variadic::None,
705        return_type: ValueType::Vector,
706        experimental: true,
707    },
708    // Info function
709    Function {
710        name: "info",
711        arg_types: &[ValueType::Vector, ValueType::Vector],
712        variadic: Variadic::Optional(1),
713        return_type: ValueType::Vector,
714        experimental: true,
715    },
716];
717
718/// Look up a function by name.
719///
720/// Returns `None` if the function is not a known built-in.
721pub fn get_function(name: &str) -> Option<&'static Function> {
722    FUNCTIONS.iter().find(|f| f.name == name)
723}
724
725/// Check if a name is a known built-in function.
726pub fn is_function(name: &str) -> bool {
727    get_function(name).is_some()
728}
729
730#[cfg(test)]
731mod tests {
732    use super::*;
733
734    #[test]
735    fn test_get_function() {
736        assert!(get_function("rate").is_some());
737        assert!(get_function("abs").is_some());
738        assert!(get_function("nonexistent").is_none());
739    }
740
741    #[test]
742    fn test_function_min_max_args() {
743        let rate = get_function("rate").unwrap();
744        assert_eq!(rate.min_args(), 1);
745        assert_eq!(rate.max_args(), Some(1));
746
747        let round = get_function("round").unwrap();
748        assert_eq!(round.min_args(), 1);
749        assert_eq!(round.max_args(), Some(2));
750
751        let label_join = get_function("label_join").unwrap();
752        assert_eq!(label_join.min_args(), 3);
753        assert_eq!(label_join.max_args(), None);
754
755        let time = get_function("time").unwrap();
756        assert_eq!(time.min_args(), 0);
757        assert_eq!(time.max_args(), Some(0));
758    }
759
760    #[test]
761    fn test_all_functions_defined() {
762        // Check that we have the main functions
763        let expected_functions = [
764            "abs",
765            "ceil",
766            "floor",
767            "rate",
768            "irate",
769            "increase",
770            "sum_over_time",
771            "avg_over_time",
772            "time",
773            "timestamp",
774            "label_replace",
775            "label_join",
776            "histogram_quantile",
777            "clamp",
778            "round",
779            "sort",
780            "sort_desc",
781        ];
782
783        for name in expected_functions {
784            assert!(get_function(name).is_some(), "Missing function: {}", name);
785        }
786    }
787}