From: Wolfgang Bumiller Date: Fri, 15 Jan 2021 10:06:15 +0000 (+0100) Subject: add tools::json for canonical json generation X-Git-Tag: v1.0.7~232 X-Git-Url: https://git.proxmox.com/?p=proxmox-backup.git;a=commitdiff_plain;h=9ff747ef50407a6675c291074277e4fbfd48ae67 add tools::json for canonical json generation moving this from backup::manifest, no functional changes Signed-off-by: Wolfgang Bumiller --- diff --git a/src/tools.rs b/src/tools.rs index 599bbd04..d96cd647 100644 --- a/src/tools.rs +++ b/src/tools.rs @@ -28,6 +28,7 @@ pub mod format; pub mod fs; pub mod fuse_loop; pub mod http; +pub mod json; pub mod logrotate; pub mod loopdev; pub mod lru_cache; diff --git a/src/tools/json.rs b/src/tools/json.rs new file mode 100644 index 00000000..c81afccb --- /dev/null +++ b/src/tools/json.rs @@ -0,0 +1,49 @@ +use anyhow::{bail, Error}; +use serde_json::Value; + +// Generate canonical json +pub fn to_canonical_json(value: &Value) -> Result, Error> { + let mut data = Vec::new(); + write_canonical_json(value, &mut data)?; + Ok(data) +} + +pub fn write_canonical_json(value: &Value, output: &mut Vec) -> Result<(), Error> { + match value { + Value::Null => bail!("got unexpected null value"), + Value::String(_) | Value::Number(_) | Value::Bool(_) => { + serde_json::to_writer(output, &value)?; + } + Value::Array(list) => { + output.push(b'['); + let mut iter = list.iter(); + if let Some(item) = iter.next() { + write_canonical_json(item, output)?; + for item in iter { + output.push(b','); + write_canonical_json(item, output)?; + } + } + output.push(b']'); + } + Value::Object(map) => { + output.push(b'{'); + let mut keys: Vec<&str> = map.keys().map(String::as_str).collect(); + keys.sort(); + let mut iter = keys.into_iter(); + if let Some(key) = iter.next() { + serde_json::to_writer(&mut *output, &key)?; + output.push(b':'); + write_canonical_json(&map[key], output)?; + for key in iter { + output.push(b','); + serde_json::to_writer(&mut *output, &key)?; + output.push(b':'); + write_canonical_json(&map[key], output)?; + } + } + output.push(b'}'); + } + } + Ok(()) +}