1use serde_json::Value as Json;
12
13#[must_use]
16pub fn reference_path(path: &str) -> String {
17 format!("/{}", storage_path(path))
18}
19
20#[must_use]
23pub fn storage_path(path: &str) -> &str {
24 path.trim_start_matches('/')
25}
26
27#[must_use]
29pub fn reference_json(v: &Json) -> Json {
30 match v.as_str() {
31 Some(s) => Json::String(reference_path(s)),
32 None => v.clone(),
33 }
34}
35
36#[must_use]
39pub fn reference_keyed(v: &Json) -> Json {
40 match v {
41 Json::Object(m) => Json::Object(
42 m.iter()
43 .map(|(k, x)| (reference_path(k), x.clone()))
44 .collect(),
45 ),
46 other => other.clone(),
47 }
48}
49
50pub fn root_field(v: &mut Json, key: &str) {
53 if let Some(m) = v.as_object_mut()
54 && let Some(Json::String(s)) = m.get(key)
55 {
56 let rooted = reference_path(s);
57 m.insert(key.to_owned(), Json::String(rooted));
58 }
59}
60
61#[cfg(test)]
62mod tests {
63 use super::*;
64 use serde_json::json;
65
66 #[test]
67 fn the_two_forms() {
68 assert_eq!(reference_path("a/b.md"), "/a/b.md");
69 assert_eq!(reference_path("/a/b.md"), "/a/b.md");
70 assert_eq!(reference_path("//a.md"), "/a.md");
71 assert_eq!(reference_path(""), "/");
72 assert_eq!(storage_path("/a.md"), "a.md");
73 assert_eq!(storage_path("a.md"), "a.md");
74 assert_eq!(storage_path("///a.md"), "a.md");
75 assert_eq!(storage_path(""), "");
76 assert_eq!(reference_json(&json!("x.md")), json!("/x.md"));
77 assert_eq!(reference_json(&json!(null)), json!(null));
78 let keyed = reference_keyed(&json!({ "a.md": 1, "/b.md": 2 }));
79 assert_eq!(
80 keyed.as_object().unwrap().keys().collect::<Vec<_>>(),
81 ["/a.md", "/b.md"]
82 );
83 let mut v = json!({ "path": "a.md", "n": 1 });
84 root_field(&mut v, "path");
85 root_field(&mut v, "n");
86 root_field(&mut v, "nope");
87 assert_eq!(v, json!({ "path": "/a.md", "n": 1 }));
88 }
89}