45 lines
1.2 KiB
Rust
45 lines
1.2 KiB
Rust
use std::collections::BTreeMap;
|
|
|
|
use eyre::{bail, Context};
|
|
use serde::Serialize;
|
|
use serde_json::{Map, Value};
|
|
|
|
#[derive(Default)]
|
|
pub struct Output {
|
|
elements: BTreeMap<&'static str, Value>,
|
|
}
|
|
|
|
impl Output {
|
|
pub fn write(&mut self, key: &'static str, v: &impl Serialize) -> eyre::Result<()> {
|
|
let v = serde_json::to_value(v).wrap_err("failed to serialize output")?;
|
|
if self.elements.insert(key, v).is_some() {
|
|
bail!("duplicated output key {key:?}");
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
pub fn write_append(&mut self, key: &'static str, v: &impl Serialize) -> eyre::Result<()> {
|
|
let Value::Object(mut v) =
|
|
serde_json::to_value(v).wrap_err("failed to serialize output")?
|
|
else {
|
|
bail!("tried to append non-object");
|
|
};
|
|
|
|
let Value::Object(entry) = self.elements.entry(key).or_insert(Map::new().into()) else {
|
|
bail!("tried to append to non-object");
|
|
};
|
|
|
|
entry.append(&mut v);
|
|
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
impl Drop for Output {
|
|
fn drop(&mut self) {
|
|
let out =
|
|
serde_json::to_string_pretty(&self.elements).expect("can serialize output as json");
|
|
println!("{out}",);
|
|
}
|
|
}
|