(&mut self)
| 105 | } |
| 106 | |
| 107 | fn parse_postfix(&mut self) -> Result<Expr, PromqlError> { |
| 108 | let mut expr = self.parse_primary()?; |
| 109 | |
| 110 | if matches!(self.peek(), Token::LBracket) { |
| 111 | self.advance(); |
| 112 | let range = self.parse_duration()?; |
| 113 | let step = if matches!(self.peek(), Token::Colon) { |
| 114 | self.advance(); |
| 115 | if matches!(self.peek(), Token::RBracket) { |
| 116 | None |
| 117 | } else { |
| 118 | Some(self.parse_duration()?) |
| 119 | } |
| 120 | } else { |
| 121 | None |
| 122 | }; |
| 123 | self.expect(&Token::RBracket)?; |
| 124 | |
| 125 | if step.is_some() || !matches!(expr, Expr::VectorSelector { .. }) { |
| 126 | expr = Expr::Subquery { |
| 127 | expr: Box::new(expr), |
| 128 | range, |
| 129 | step, |
| 130 | }; |
| 131 | } else { |
| 132 | expr = Expr::MatrixSelector { |
| 133 | selector: Box::new(expr), |
| 134 | range, |
| 135 | }; |
| 136 | } |
| 137 | } |
| 138 | |
| 139 | if self.try_keyword("offset") { |
| 140 | let neg = matches!(self.peek(), Token::Sub); |
| 141 | if neg { |
| 142 | self.advance(); |
| 143 | } |
| 144 | let mut dur = self.parse_duration()?; |
| 145 | if neg { |
| 146 | dur = Duration(-dur.ms()); |
| 147 | } |
| 148 | expr = apply_offset(expr, dur); |
| 149 | } |
| 150 | |
| 151 | Ok(expr) |
| 152 | } |
| 153 | |
| 154 | fn parse_primary(&mut self) -> Result<Expr, PromqlError> { |
| 155 | match self.peek().clone() { |
no test coverage detected