(
tokens: &[String],
pos: &mut usize,
)
| 271 | } |
| 272 | |
| 273 | fn parse_value_ref( |
| 274 | tokens: &[String], |
| 275 | pos: &mut usize, |
| 276 | ) -> Result<PredicateValue, PredicateParseError> { |
| 277 | if *pos >= tokens.len() { |
| 278 | return Err(PredicateParseError::UnexpectedEnd); |
| 279 | } |
| 280 | |
| 281 | let token = &tokens[*pos]; |
| 282 | |
| 283 | // $auth.* reference |
| 284 | if let Some(field) = token.strip_prefix("$auth.") { |
| 285 | *pos += 1; |
| 286 | return Ok(PredicateValue::AuthRef(field.to_string())); |
| 287 | } |
| 288 | |
| 289 | // Quoted string literal |
| 290 | if token.starts_with('\'') && token.ends_with('\'') && token.len() >= 2 { |
| 291 | *pos += 1; |
| 292 | let inner = &token[1..token.len() - 1]; |
| 293 | return Ok(PredicateValue::Literal(serde_json::Value::String( |
| 294 | inner.to_string(), |
| 295 | ))); |
| 296 | } |
| 297 | |
| 298 | // Numeric literal |
| 299 | if token.starts_with(|c: char| c.is_ascii_digit() || c == '-') { |
| 300 | if let Ok(n) = token.parse::<i64>() { |
| 301 | *pos += 1; |
| 302 | return Ok(PredicateValue::Literal(serde_json::json!(n))); |
| 303 | } |
| 304 | if let Ok(f) = token.parse::<f64>() { |
| 305 | *pos += 1; |
| 306 | return Ok(PredicateValue::Literal(serde_json::json!(f))); |
| 307 | } |
| 308 | } |
| 309 | |
| 310 | // Boolean literals |
| 311 | match token.to_lowercase().as_str() { |
| 312 | "true" => { |
| 313 | *pos += 1; |
| 314 | return Ok(PredicateValue::Literal(serde_json::json!(true))); |
| 315 | } |
| 316 | "false" => { |
| 317 | *pos += 1; |
| 318 | return Ok(PredicateValue::Literal(serde_json::json!(false))); |
| 319 | } |
| 320 | "null" => { |
| 321 | *pos += 1; |
| 322 | return Ok(PredicateValue::Literal(serde_json::Value::Null)); |
| 323 | } |
| 324 | _ => {} |
| 325 | } |
| 326 | |
| 327 | // Document field identifier (anything that's not a keyword). |
| 328 | let upper = token.to_uppercase(); |
| 329 | if !matches!( |
| 330 | upper.as_str(), |
no test coverage detected