use std::path::{Path, PathBuf};
use anyhow::Result;
use serde_json::{json, Value};
use super::{message_path, outbox_path, Message, Mode, Verdict};
#[derive(Debug, Clone, PartialEq, Eq)]
pub(crate) struct OfficialRef {
pub(crate) delegated: bool,
pub(crate) tool: Option<String>,
pub(crate) to_form: Option<String>,
}
impl OfficialRef {
pub(crate) fn none() -> Self {
OfficialRef {
delegated: false,
tool: None,
to_form: None,
}
}
pub(crate) fn to_json(&self) -> Value {
json!({
"delegated": self.delegated,
"tool": self.tool,
"to_form": self.to_form,
})
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub(crate) struct OutboxLine {
pub(crate) id: String,
pub(crate) ts_utc: String,
pub(crate) to_lane: String,
pub(crate) to_session: String,
pub(crate) mode: Mode,
pub(crate) verdict: Verdict,
pub(crate) channel: String,
pub(crate) official: OfficialRef,
}
impl OutboxLine {
pub(crate) fn to_json(&self) -> Value {
json!({
"id": self.id,
"ts_utc": self.ts_utc,
"to_lane": self.to_lane,
"to_session": self.to_session,
"mode": self.mode.as_str(),
"verdict": self.verdict.as_str(),
"channel": self.channel,
"official": self.official.to_json(),
})
}
}
pub(crate) fn append_outbox(root: &Path, line: &OutboxLine) -> Result<()> {
super::append_line(&outbox_path(root), &serde_json::to_string(&line.to_json())?)
}
pub(crate) fn write_message(root: &Path, msg: &Message) -> Result<PathBuf> {
let path = message_path(root, &msg.id)?;
super::write_atomic(&path, &serde_json::to_string(&msg.to_json())?)?;
Ok(path)
}
pub(crate) fn read_message(root: &Path, id: &str) -> Result<Option<Message>> {
let path = message_path(root, id)?;
let Ok(raw) = std::fs::read_to_string(&path) else {
return Ok(None);
};
let Ok(v) = serde_json::from_str::<Value>(&raw) else {
return Ok(None);
};
Ok(Message::from_json(&v))
}