| 164 | } |
| 165 | |
| 166 | fn lex_string(bytes: &[u8], start: usize) -> Result<(Token, usize), PromqlError> { |
| 167 | let quote = bytes[start]; |
| 168 | let mut i = start + 1; |
| 169 | let mut s = String::new(); |
| 170 | |
| 171 | while i < bytes.len() { |
| 172 | if bytes[i] == quote { |
| 173 | return Ok((Token::String(s), i + 1)); |
| 174 | } |
| 175 | if bytes[i] == b'\\' && quote != b'`' && i + 1 < bytes.len() { |
| 176 | i += 1; |
| 177 | match bytes[i] { |
| 178 | b'n' => s.push('\n'), |
| 179 | b't' => s.push('\t'), |
| 180 | b'\\' => s.push('\\'), |
| 181 | b'\'' => s.push('\''), |
| 182 | b'"' => s.push('"'), |
| 183 | c => { |
| 184 | s.push('\\'); |
| 185 | s.push(c as char); |
| 186 | } |
| 187 | } |
| 188 | } else { |
| 189 | s.push(bytes[i] as char); |
| 190 | } |
| 191 | i += 1; |
| 192 | } |
| 193 | Err(PromqlError::InvalidString { |
| 194 | detail: format!("unterminated string starting at position {start}"), |
| 195 | }) |
| 196 | } |
| 197 | |
| 198 | fn lex_number_or_duration(bytes: &[u8], start: usize) -> Result<(Token, usize), PromqlError> { |
| 199 | let mut i = start; |