prometheus_parser/types/
expression.rs

1// (C) Copyright 2019-2020 Hewlett Packard Enterprise Development LP
2
3use std::fmt;
4
5use super::function::Function;
6use super::group::Group;
7use super::operator::Operator;
8use super::return_value::{LabelSetOp, ReturnKind, ReturnValue};
9use super::selector::Selector;
10
11/// A root expression node.
12///
13/// These are all valid root expression types.
14#[derive(PartialEq, Clone)]
15pub enum Expression {
16  /// A single scalar float
17  Float(f64),
18
19  /// A single scalar string.
20  ///
21  /// Prometheus' docs claim strings aren't currently implemented, but they're
22  /// valid as function arguments.
23  String(String),
24
25  /// A metric selector
26  Selector(Selector),
27
28  /// A grouped expression wrapped in parentheses
29  Group(Group),
30
31  /// A function call
32  Function(Function),
33
34  /// A binary operator expression
35  Operator(Operator)
36}
37
38// For handling groups when testing
39impl Expression {
40  /// Wraps this Expression in a Group, consuming this Expression but returning
41  /// an owned Group.
42  pub fn group(self) -> Expression {
43    Group::new(self).wrap()
44  }
45
46  /// Determines a predicted `ReturnValue` for this Expression. A `ReturnValue`
47  /// includes a predicted data type and a set of label operations that may
48  /// affect which labels are returned.
49  pub fn return_value(&self) -> ReturnValue {
50    match self {
51      Expression::Float(_) => ReturnValue {
52        kind: ReturnKind::Scalar,
53        label_ops: vec![LabelSetOp::clear(self.clone(), None)]
54      },
55      Expression::String(_) => ReturnValue {
56        kind: ReturnKind::String,
57        label_ops: vec![LabelSetOp::clear(self.clone(), None)]
58      },
59      Expression::Selector(s) => s.return_value(),
60      Expression::Group(g) => g.return_value(),
61      Expression::Function(f) => f.return_value(),
62      Expression::Operator(o) => o.return_value()
63    }
64  }
65
66  /// If this Expression is a Float, returns its value. Otherwise, returns None.
67  pub fn as_f64(&self) -> Option<f64> {
68    if let Expression::Float(f) = self {
69      Some(*f)
70    } else {
71      None
72    }
73  }
74
75  /// If this Expression is a String, returns its value. Otherwise, returns
76  /// None.
77  pub fn as_str(&self) -> Option<&str> {
78    if let Expression::String(s) = self {
79      Some(s.as_str())
80    } else {
81      None
82    }
83  }
84}
85
86impl fmt::Debug for Expression {
87  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
88    // don't bother formatting the Expression enum itself, this just creates
89    // tons of whitespace if we pretty-print
90    // this makes the output significantly more readable, if a bit misleading
91
92    // there's gotta be a better way to pass through flags...
93    if f.alternate() {
94      match self {
95        Expression::Float(val) => write!(f, "{:#?}", val),
96        Expression::String(val) => write!(f, "{:#?}", val),
97        Expression::Selector(val) => write!(f, "{:#?}", val),
98        Expression::Group(val) => write!(f, "{:#?}", val),
99        Expression::Function(val) => write!(f, "{:#?}", val),
100        Expression::Operator(val) => write!(f, "{:#?}", val),
101      }
102    } else {
103      match self {
104        Expression::Float(val) => write!(f, "{:?}", val),
105        Expression::String(val) => write!(f, "{:?}", val),
106        Expression::Selector(val) => write!(f, "{:?}", val),
107        Expression::Group(val) => write!(f, "{:?}", val),
108        Expression::Function(val) => write!(f, "{:?}", val),
109        Expression::Operator(val) => write!(f, "{:?}", val),
110      }
111    }
112  }
113}
114
115impl fmt::Display for Expression {
116  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
117    match self {
118      Expression::Float(val) => write!(f, "{}", val),
119      Expression::String(val) => write!(f, "{}", val),
120      Expression::Selector(val) => write!(f, "{}", val),
121      Expression::Group(val) => write!(f, "{}", val),
122      Expression::Function(val) => write!(f, "{}", val),
123      Expression::Operator(val) => write!(f, "{}", val),
124    }
125  }
126}
127
128pub type BExpression = Box<Expression>;