use anyhow::{Context, Result};
use pushkin_core::board::Board;
use std::path::PathBuf;
pub const BOARD_DB: &str = ".pushkin/board.db";
pub enum BoardVerb {
Register,
Status { message: String },
Peers,
Broadcast { message: String },
Send { to: String, message: String },
Read,
Claim { path: String },
Release { path: String },
Claims,
}
pub struct BoardArgs {
pub verb: BoardVerb,
pub run: String,
pub agent: String,
}
pub fn run(args: BoardArgs) -> Result<i32> {
let board = open_board(&args.run)?;
match args.verb {
BoardVerb::Register => {
board.register(&args.agent)?;
println!("pushkin board: {} registered in {}", args.agent, args.run);
}
BoardVerb::Status { message } => {
board.set_status(&args.agent, &message)?;
println!("pushkin board: status recorded");
}
BoardVerb::Peers => {
for peer in board.peers(&args.agent)? {
match peer.status {
Some(status) => println!("{} โ {status}", peer.agent),
None => println!("{}", peer.agent),
}
}
}
BoardVerb::Broadcast { message } => {
board.broadcast(&args.agent, &message)?;
println!("pushkin board: broadcast queued");
}
BoardVerb::Send { to, message } => {
board.send(&args.agent, &to, &message)?;
println!("pushkin board: message queued for {to}");
}
BoardVerb::Read => {
for message in board.read(&args.agent)? {
println!("[{}] {}", message.from_agent, message.body);
}
}
BoardVerb::Claim { path } => {
board
.claim(&args.agent, &path)
.with_context(|| format!("cannot claim {path}"))?;
println!("pushkin board: {} claimed {path}", args.agent);
}
BoardVerb::Release { path } => {
if board.release(&args.agent, &path)? {
println!("pushkin board: {} released {path}", args.agent);
} else {
println!(
"pushkin board: no claim on {path} held by {} โ nothing released",
args.agent
);
}
}
BoardVerb::Claims => {
for claim in board.claims()? {
println!("{} held by {}", claim.path_glob, claim.agent);
}
}
}
Ok(0)
}
pub fn open_board(run: &str) -> Result<Board> {
let path = PathBuf::from(BOARD_DB);
if let Some(parent) = path.parent() {
std::fs::create_dir_all(parent).context("cannot create .pushkin/")?;
}
Ok(Board::open(&path, run)?)
}