pub fn json_path_candidates(json_path: &str) -> Vec<String> {
json_path
.split(" / ")
.map(|segment| {
segment
.trim()
.chars()
.take_while(|c| c.is_alphanumeric() || matches!(c, '.' | '_' | '[' | ']' | '*'))
.collect::<String>()
})
.filter(|segment| !segment.is_empty())
.collect()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn splits_compound_paths() {
assert_eq!(
json_path_candidates("summary.grade / summary.certificate"),
vec!["summary.grade", "summary.certificate"]
);
}
#[test]
fn drops_trailing_prose() {
assert_eq!(
json_path_candidates("pages[].detail.modules.*.score and nested dimension scores"),
vec!["pages[].detail.modules.*.score"]
);
}
#[test]
fn single_path_is_unchanged() {
assert_eq!(
json_path_candidates("pages[].risk.score"),
vec!["pages[].risk.score"]
);
}
}