use serde_json::Value;
use std::path::Path;
use super::{Gesture, Query, deposit, help};
pub(crate) mod argv;
pub const TIMEOUT_EXIT: i32 = 124;
pub const USAGE_EXIT: i32 = 2;
const VERB: &str = "gesture";
pub fn run(
state_root: &Path,
args: &[String],
seed: &str,
waits: u32,
wait: &mut dyn FnMut(),
) -> i32 {
let (gesture, value) = match argv::read_gesture(VERB, args) {
Ok(read) => read,
Err(e) => {
eprintln!("yog gesture: {e}");
return USAGE_EXIT;
}
};
if let Gesture::Ask(Query::Help { verb }) = &gesture {
println!("{}", help::render(&help::rows(verb.as_deref())));
return 0;
}
let (id, deposited) = match deposit::mint(state_root, seed)
.and_then(|id| deposit::deposit(state_root, &id, &value).map(|path| (id, path)))
{
Ok(minted) => minted,
Err(e) => {
eprintln!("yog gesture: deposit failed: {e}");
return 1;
}
};
for _ in 0..waits {
if let Some(reply) = deposit::read_reply(state_root, &id) {
println!("{reply}");
let ok = reply.get("ok").and_then(Value::as_bool).unwrap_or(false);
return i32::from(!ok);
}
wait();
}
eprintln!(
"yog gesture: no consumer answered; the deposit remains at {}",
deposited.display()
);
TIMEOUT_EXIT
}
#[cfg(test)]
mod tests;