Skip to main content

repe/
json_pointer.rs

1use serde_json::Value;
2
3/// Parse a JSON Pointer string into unescaped reference tokens.
4/// Implements RFC 6901 unescaping: `~1` -> `/`, `~0` -> `~`.
5pub fn parse(ptr: &str) -> Vec<String> {
6    if ptr.is_empty() {
7        return Vec::new();
8    }
9    let s = ptr.strip_prefix('/').unwrap_or(ptr);
10    s.split('/')
11        .map(|t| t.replace("~1", "/").replace("~0", "~"))
12        .collect()
13}
14
15/// Evaluate a JSON Pointer against a serde_json::Value and return a reference.
16pub fn evaluate<'a>(v: &'a Value, ptr: &str) -> Option<&'a Value> {
17    let mut cur = v;
18    for tok in parse(ptr) {
19        match cur {
20            Value::Object(map) => {
21                cur = map.get(&tok)?;
22            }
23            Value::Array(arr) => {
24                let idx: usize = tok.parse().ok()?;
25                cur = arr.get(idx)?;
26            }
27            _ => return None,
28        }
29    }
30    Some(cur)
31}