use serde_json::{Map, Value, json};
use super::super::fields::opt_str_of;
use super::super::start::opt_field;
use super::super::str_of;
use crate::boundary::Query;
pub(super) const FOLLOW: &str = "follow";
pub(super) fn at(op: &str, workspace: &str, agent: &str) -> Value {
Value::Object(at_map(op, workspace, agent))
}
fn at_map(op: &str, workspace: &str, agent: &str) -> Map<String, Value> {
let mut map = Map::new();
map.insert("op".to_owned(), json!(op));
map.insert("workspace".to_owned(), json!(workspace));
map.insert("agent".to_owned(), json!(agent));
map
}
pub(super) fn step(workspace: &str, agent: &str, seq: &str) -> Value {
let mut map = at_map("step", workspace, agent);
map.insert("seq".to_owned(), json!(seq));
Value::Object(map)
}
pub(super) fn files(
workspace: &str,
agent: &str,
path: Option<&String>,
at: Option<&String>,
) -> Value {
let mut map = at_map("files", workspace, agent);
opt_field(&mut map, "path", path);
opt_field(&mut map, "at", at);
Value::Object(map)
}
pub(super) fn governing(workspace: &str, agent: &str, at: Option<&String>) -> Value {
let mut map = at_map("governing", workspace, agent);
opt_field(&mut map, "at", at);
Value::Object(map)
}
pub(super) fn read(op: &str, o: &Map<String, Value>) -> Result<Option<Query>, String> {
Ok(Some(match op {
"transcript" => {
let (workspace, agent) = address(o)?;
Query::Transcript { workspace, agent }
}
FOLLOW => {
let (workspace, agent) = address(o)?;
Query::Follow { workspace, agent }
}
"steps" => {
let (workspace, agent) = address(o)?;
Query::Steps { workspace, agent }
}
"step" => {
let (workspace, agent) = address(o)?;
Query::Step {
workspace,
agent,
seq: str_of(o, "seq")?,
}
}
"files" => {
let (workspace, agent) = address(o)?;
Query::Files {
workspace,
agent,
path: opt_str_of(o, "path")?,
at: opt_str_of(o, "at")?,
}
}
"governing" => {
let (workspace, agent) = address(o)?;
Query::Governing {
workspace,
agent,
at: opt_str_of(o, "at")?,
}
}
"rail" => {
let (workspace, agent) = address(o)?;
Query::Rail { workspace, agent }
}
"inbox" => {
let (workspace, agent) = address(o)?;
Query::Inbox { workspace, agent }
}
"agent" => {
let (workspace, agent) = address(o)?;
Query::Agent { workspace, agent }
}
_ => return Ok(None),
}))
}
fn address(o: &Map<String, Value>) -> Result<(String, String), String> {
Ok((str_of(o, "workspace")?, str_of(o, "agent")?))
}