use serde::Serialize;
use crate::output::CliReport;
use crate::output::human::{Human, Table};
fn yesno(b: bool) -> String {
if b { "yes".into() } else { "no".into() }
}
#[derive(Serialize)]
pub struct AgentRow {
pub id: String,
pub configured: bool,
pub in_catalog: bool,
pub description: String,
}
#[derive(Serialize)]
pub struct AgentRegistryRow {
pub id: String,
pub version: String,
pub install: String,
pub description: String,
}
#[derive(Serialize)]
pub struct AgentsListReport {
pub agents: Vec<AgentRow>,
#[serde(skip_serializing_if = "Option::is_none")]
pub registry: Option<Vec<AgentRegistryRow>>,
}
impl CliReport for AgentsListReport {
fn render(&self, h: &mut Human<'_>) -> std::io::Result<()> {
let mut t = Table::new(["ID", "CONFIGURED", "CATALOG", "DESCRIPTION"]);
for a in &self.agents {
t.push([
a.id.clone(),
yesno(a.configured),
yesno(a.in_catalog),
a.description.clone(),
]);
}
h.table(&t)?;
if let Some(registry) = &self.registry {
h.line("")?;
h.line(&format!("ACP registry ({} agents):", registry.len()))?;
let mut t = Table::new(["ID", "VERSION", "INSTALL", "DESCRIPTION"]);
for r in registry {
t.push([
r.id.clone(),
r.version.clone(),
r.install.clone(),
r.description.clone(),
]);
}
h.table(&t)?;
h.line("")?;
h.line(" install a stub with: bitrouter agents install <id>")?;
}
Ok(())
}
}
#[derive(Serialize)]
pub struct AgentCheckRow {
pub id: String,
pub ok: bool,
#[serde(skip_serializing_if = "Option::is_none")]
pub latency_ms: Option<u128>,
#[serde(skip_serializing_if = "Option::is_none")]
pub error: Option<String>,
}
#[derive(Serialize)]
pub struct AgentsCheckReport {
pub agents: Vec<AgentCheckRow>,
}
impl CliReport for AgentsCheckReport {
fn render(&self, h: &mut Human<'_>) -> std::io::Result<()> {
let mut t = Table::new(["AGENT", "STATUS", "LATENCY"]);
for a in &self.agents {
t.push([
a.id.clone(),
if a.ok { "ok".into() } else { "FAIL".into() },
a.latency_ms
.map(|ms| format!("{ms}ms"))
.unwrap_or_else(|| "-".into()),
]);
}
h.table(&t)
}
}
#[derive(Serialize)]
pub struct AgentInstallReport {
pub id: String,
pub yaml: String,
}
impl CliReport for AgentInstallReport {
fn render(&self, h: &mut Human<'_>) -> std::io::Result<()> {
for line in self.yaml.lines() {
h.line(line)?;
}
Ok(())
}
}