use std::fmt;
use anyhow::Result;
use clap::{Args, Subcommand};
use io_replica::collection::ReplicaCollectionId;
use pimalaya_cli::{
printer::Printer,
table::{Cell, ContentArrangement, Table, presets::UTF8_FULL},
};
use serde::Serialize;
use crate::cli::{StoreFlags, or_dash, report};
#[derive(Debug, Subcommand)]
pub enum CollectionCommand {
List(CollectionListCommand),
}
impl CollectionCommand {
pub fn execute(self, printer: &mut impl Printer, store: &StoreFlags) -> Result<()> {
match self {
Self::List(cmd) => cmd.execute(printer, store),
}
}
}
#[derive(Debug, Args)]
pub struct CollectionListCommand;
impl CollectionListCommand {
pub fn execute(self, printer: &mut impl Printer, store: &StoreFlags) -> Result<()> {
let store = store.read()?;
let mut rows = Vec::new();
for collection in store.list_collections().map_err(report)? {
let id = ReplicaCollectionId(collection.id.clone());
rows.push(CollectionRow {
live: store.count_items(&collection.id).map_err(report)?,
retained: store.count_retained(&id).map_err(report)?.max(0) as u64,
id: collection.id,
kind: collection.kind,
name: collection.name,
generation: collection.generation,
});
}
printer.out(CollectionsOutput(rows))
}
}
#[derive(Debug, Serialize)]
pub struct CollectionRow {
pub id: String,
pub kind: String,
pub name: String,
pub generation: i64,
pub live: u64,
pub retained: u64,
}
#[derive(Debug, Serialize)]
#[serde(transparent)]
pub struct CollectionsOutput(pub Vec<CollectionRow>);
impl fmt::Display for CollectionsOutput {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if self.0.is_empty() {
return writeln!(f, "This store holds no collection yet");
}
let mut table = Table::new();
table
.load_style(UTF8_FULL)
.set_content_arrangement(ContentArrangement::Dynamic)
.set_header(vec![
Cell::new("ID"),
Cell::new("KIND"),
Cell::new("NAME"),
Cell::new("GEN"),
Cell::new("LIVE"),
Cell::new("RETAINED"),
]);
for row in &self.0 {
table.add_row(vec![
Cell::new(&row.id),
Cell::new(or_dash(Some(row.kind.as_str()).filter(|k| !k.is_empty()))),
Cell::new(&row.name),
Cell::new(row.generation),
Cell::new(row.live),
Cell::new(row.retained),
]);
}
writeln!(f, "{table}")
}
}