Generalise a URL path for policy rules. Heuristics: - Strip query strings. - If the last segment looks like an ID (hex, UUID, or numeric), replace with `*`. - Preserve all other segments verbatim.
(raw: &str)
| 378 | /// with `*`. |
| 379 | /// - Preserve all other segments verbatim. |
| 380 | fn generalise_path(raw: &str) -> String { |
| 381 | // Strip query string. |
| 382 | let path = raw.split('?').next().unwrap_or(raw); |
| 383 | |
| 384 | let segments: Vec<&str> = path.split('/').collect(); |
| 385 | if segments.len() <= 1 { |
| 386 | return path.to_string(); |
| 387 | } |
| 388 | |
| 389 | let last = segments.last().unwrap_or(&""); |
| 390 | |
| 391 | // Replace ID-like trailing segments with a wildcard. |
| 392 | if looks_like_id(last) { |
| 393 | let mut out = segments[..segments.len() - 1].join("/"); |
| 394 | out.push_str("/*"); |
| 395 | return out; |
| 396 | } |
| 397 | |
| 398 | path.to_string() |
| 399 | } |
| 400 | |
| 401 | /// Heuristic: does a path segment look like an opaque identifier? |
| 402 | fn looks_like_id(segment: &str) -> bool { |
no test coverage detected