use clap::Args;
use microsandbox::sandbox::{Sandbox, SandboxConfig, SandboxHandle, SandboxStatus};
use crate::ui;
#[derive(Debug, Args)]
pub struct ListArgs {
#[arg(long)]
pub running: bool,
#[arg(long)]
pub stopped: bool,
#[arg(long, value_name = "FORMAT", value_parser = ["json"])]
pub format: Option<String>,
#[arg(short, long)]
pub quiet: bool,
}
pub async fn run(args: ListArgs) -> anyhow::Result<()> {
let sandboxes = Sandbox::list().await?;
let filtered: Vec<_> = sandboxes
.into_iter()
.filter(|s| {
if args.running {
s.status() == SandboxStatus::Running
} else if args.stopped {
s.status() == SandboxStatus::Stopped
} else {
true
}
})
.collect();
if args.format.as_deref() == Some("json") {
print_json(&filtered)?;
return Ok(());
}
if args.quiet {
for s in &filtered {
println!("{}", s.name());
}
return Ok(());
}
if filtered.is_empty() {
eprintln!("No sandboxes found.");
return Ok(());
}
let mut table = ui::Table::new(&["NAME", "IMAGE", "STATUS", "CREATED"]);
for s in &filtered {
let image = extract_image(s.config_json());
let status = format!("{:?}", s.status());
let created = s
.created_at()
.as_ref()
.map(ui::format_datetime)
.unwrap_or_else(|| "-".to_string());
table.add_row(vec![
s.name().to_string(),
image,
ui::format_status(&status),
created,
]);
}
table.print();
Ok(())
}
fn extract_image(config_json: &str) -> String {
serde_json::from_str::<SandboxConfig>(config_json)
.ok()
.map(|c| match c.image {
microsandbox::sandbox::RootfsSource::Oci(ref s) => s.clone(),
microsandbox::sandbox::RootfsSource::Bind(ref p) => p.display().to_string(),
microsandbox::sandbox::RootfsSource::DiskImage { ref path, .. } => {
path.display().to_string()
}
})
.unwrap_or_else(|| "-".to_string())
}
fn print_json(sandboxes: &[SandboxHandle]) -> anyhow::Result<()> {
let entries: Vec<serde_json::Value> = sandboxes
.iter()
.map(|s| {
serde_json::json!({
"name": s.name(),
"status": format!("{:?}", s.status()),
"created_at": s.created_at().map(|dt| ui::format_datetime(&dt)),
"image": extract_image(s.config_json()),
})
})
.collect();
println!("{}", serde_json::to_string_pretty(&entries)?);
Ok(())
}