use serde_json::Value as Json;
#[must_use]
pub fn reference_path(path: &str) -> String {
format!("/{}", storage_path(path))
}
#[must_use]
pub fn storage_path(path: &str) -> &str {
path.trim_start_matches('/')
}
#[must_use]
pub fn reference_json(v: &Json) -> Json {
match v.as_str() {
Some(s) => Json::String(reference_path(s)),
None => v.clone(),
}
}
#[must_use]
pub fn reference_keyed(v: &Json) -> Json {
match v {
Json::Object(m) => Json::Object(
m.iter()
.map(|(k, x)| (reference_path(k), x.clone()))
.collect(),
),
other => other.clone(),
}
}
pub fn root_field(v: &mut Json, key: &str) {
if let Some(m) = v.as_object_mut()
&& let Some(Json::String(s)) = m.get(key)
{
let rooted = reference_path(s);
m.insert(key.to_owned(), Json::String(rooted));
}
}
#[cfg(test)]
mod tests {
use super::*;
use serde_json::json;
#[test]
fn the_two_forms() {
assert_eq!(reference_path("a/b.md"), "/a/b.md");
assert_eq!(reference_path("/a/b.md"), "/a/b.md");
assert_eq!(reference_path("//a.md"), "/a.md");
assert_eq!(reference_path(""), "/");
assert_eq!(storage_path("/a.md"), "a.md");
assert_eq!(storage_path("a.md"), "a.md");
assert_eq!(storage_path("///a.md"), "a.md");
assert_eq!(storage_path(""), "");
assert_eq!(reference_json(&json!("x.md")), json!("/x.md"));
assert_eq!(reference_json(&json!(null)), json!(null));
let keyed = reference_keyed(&json!({ "a.md": 1, "/b.md": 2 }));
assert_eq!(
keyed.as_object().unwrap().keys().collect::<Vec<_>>(),
["/a.md", "/b.md"]
);
let mut v = json!({ "path": "a.md", "n": 1 });
root_field(&mut v, "path");
root_field(&mut v, "n");
root_field(&mut v, "nope");
assert_eq!(v, json!({ "path": "/a.md", "n": 1 }));
}
}