prometheus_parser/types/
misc.rs

1// (C) Copyright 2019-2020 Hewlett Packard Enterprise Development LP
2
3use std::fmt;
4
5/// A byte-index tuple representing a span of characters in a string
6///
7/// Note that spans refer to the position in the input string as read by the
8/// parser rather than the output of an expression's `Display` impl.
9#[derive(Debug, PartialEq, Eq, Copy, Clone)]
10pub struct Span {
11  pub start: usize,
12  pub end: usize
13}
14
15impl From<(usize, usize)> for Span {
16  fn from(tup: (usize, usize)) -> Span {
17    Span::new(tup.0, tup.1)
18  }
19}
20
21impl Span {
22  pub fn new(start: usize, end: usize) -> Self {
23    Span { start, end }
24  }
25
26  pub(crate) fn from_node(node: &crate::parser::Node) -> Self {
27    let span = node.as_span();
28    Span {
29      start: span.start(),
30      end: span.end()
31    }
32  }
33}
34
35impl fmt::Display for Span {
36  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
37    write!(f, "({}, {})", self.start, self.end)
38  }
39}
40
41/// A Prometheus duration
42#[derive(Debug, PartialEq, Eq, Clone, Copy)]
43pub enum PromDuration {
44  Seconds(u64),
45  Minutes(u64),
46  Hours(u64),
47  Days(u64),
48  Weeks(u64),
49  Years(u64)
50}
51
52type StringResult<T> = std::result::Result<T, String>;
53
54impl PromDuration {
55  pub fn from_pair(unit: &str, value: u64) -> StringResult<PromDuration> {
56    Ok(match unit {
57      "s" => PromDuration::Seconds(value),
58      "m" => PromDuration::Minutes(value),
59      "h" => PromDuration::Hours(value),
60      "d" => PromDuration::Days(value),
61      "w" => PromDuration::Weeks(value),
62      "y" => PromDuration::Years(value),
63      u => return Err(format!("invalid duration unit: {:?}", u))
64    })
65  }
66
67  pub fn as_char(self) -> char {
68    match self {
69      PromDuration::Seconds(_) => 's',
70      PromDuration::Minutes(_) => 'm',
71      PromDuration::Hours(_) => 'h',
72      PromDuration::Days(_) => 'd',
73      PromDuration::Weeks(_) => 'w',
74      PromDuration::Years(_) => 'y'
75    }
76  }
77}
78
79impl fmt::Display for PromDuration {
80  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
81    let v = match self {
82      PromDuration::Seconds(v) => v,
83      PromDuration::Minutes(v) => v,
84      PromDuration::Hours(v) => v,
85      PromDuration::Days(v) => v,
86      PromDuration::Weeks(v) => v,
87      PromDuration::Years(v) => v
88    };
89
90    write!(f, "{}{}", v, self.as_char())
91  }
92}
93
94/// A Subquery which converts an instant vector to a range vector by repeatedly
95/// evaluating it at set intervals into the relative past
96#[derive(Debug, PartialEq, Eq, Clone)]
97pub struct Subquery {
98  /// Duration back in time to begin the subquery
99  pub range: PromDuration,
100
101  /// Optional step size. If unset, uses the global/query default at runtime.
102  pub resolution: Option<PromDuration>,
103
104  pub span: Option<Span>
105}
106
107impl Subquery {
108  pub fn new(range: PromDuration) -> Self {
109    Subquery {
110      range,
111      resolution: None,
112      span: None
113    }
114  }
115
116  pub fn resolution(mut self, res: PromDuration) -> Self {
117    self.resolution = Some(res);
118    self
119  }
120
121  pub fn clear_resolution(mut self) -> Self {
122    self.resolution = None;
123    self
124  }
125
126  pub fn span<S: Into<Span>>(mut self, span: S) -> Self {
127    self.span = Some(span.into());
128    self
129  }
130}
131
132impl fmt::Display for Subquery {
133  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
134    if let Some(res) = self.resolution {
135      write!(f, "[{}:{}]", self.range, res)
136    } else {
137      write!(f, "[{}:]", self.range)
138    }
139  }
140}