use serde_json::{Map, Value};
use super::fields;
pub(crate) const KIND: &str = "steps";
pub const NONE: &str = "none";
pub const REFUSED: &str = "refused";
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Steps {
pub rows: Vec<StepRow>,
pub orphan: String,
pub orphan_reason: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct StepRow {
pub seq: String,
pub framing: String,
pub attempts: u64,
pub tokens: Spend,
pub commit: Option<String>,
pub started_at: Option<String>,
pub ended_at: Option<String>,
pub auth_row: Option<String>,
pub wound: String,
pub wound_reason: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Spend {
pub input: u64,
pub output: u64,
pub cache_read: u64,
pub cache_write: u64,
pub total: u64,
}
pub(crate) fn steps(obj: &Map<String, Value>) -> Result<Steps, String> {
Ok(Steps {
rows: fields::rows(obj, row)?,
orphan: fields::text(obj, "orphan")?,
orphan_reason: fields::opt_text(obj, "orphan_reason")?,
})
}
fn row(value: &Value) -> Result<StepRow, String> {
let obj: &Map<String, Value> = value.as_object().ok_or("step row: not an object")?;
Ok(StepRow {
seq: fields::text(obj, "seq")?,
framing: fields::text(obj, "framing")?,
attempts: fields::count(obj, "attempts")?,
tokens: spend(obj)?,
commit: fields::opt_text(obj, "commit")?,
started_at: fields::opt_text(obj, "started_at")?,
ended_at: fields::opt_text(obj, "ended_at")?,
auth_row: fields::opt_text(obj, "auth_row")?,
wound: fields::text(obj, "wound")?,
wound_reason: fields::opt_text(obj, "wound_reason")?,
})
}
pub(crate) fn spend(row: &Map<String, Value>) -> Result<Spend, String> {
let obj = row
.get("tokens")
.and_then(Value::as_object)
.ok_or("missing or non-object field \"tokens\"")?;
Ok(Spend {
input: fields::count(obj, "input")?,
output: fields::count(obj, "output")?,
cache_read: fields::count(obj, "cache_read")?,
cache_write: fields::count(obj, "cache_write")?,
total: fields::count(obj, "total")?,
})
}
#[cfg(test)]
mod tests;