use serde_json::Value;
use super::args;
use super::parse::act;
use crate::boundary::{Action, Gesture};
use crate::registry::mailbox::{Call, Capture, Completion, Verb, capture_of};
pub(super) fn route(verb: &str, tail: &str) -> Result<Gesture, String> {
match verb {
"invoke" => invoke(tail, verb),
_ => complete(tail, verb),
}
}
fn invoke(tail: &str, verb: &str) -> Result<Gesture, String> {
let (client, rest) = args::first_word(tail);
let (tool, input) = args::first_word(&rest);
if client.is_empty() || tool.is_empty() {
return Err(format!("/{verb}: usage: /{verb} <client> <tool> <json>"));
}
Ok(act(Action::Route(Verb::Invoke(Call {
client,
tool,
input: document(&input, verb)?,
}))))
}
fn complete(tail: &str, verb: &str) -> Result<Gesture, String> {
let (invocation, capture) = args::first_word(tail);
if invocation.is_empty() {
return Err(format!(
"/{verb}: usage: /{verb} <invocation> <json capture>"
));
}
Ok(act(Action::Route(Verb::Complete(Completion {
invocation,
capture: read_capture(&capture, verb)?,
}))))
}
fn document(tail: &str, verb: &str) -> Result<Value, String> {
let text = args::required(tail, verb, "the JSON document")?;
serde_json::from_str(&text).map_err(|e| format!("/{verb}: {e}"))
}
fn read_capture(tail: &str, verb: &str) -> Result<Capture, String> {
capture_of(&document(tail, verb)?).map_err(|e| format!("/{verb}: {e}"))
}