use std::fmt::Display; use crate::{ actions::{action::Action, fetch_all_libraries::FetchAllLibraries}, context::Context, }; use chrono::{DateTime, Utc}; use color_eyre::eyre::Result; use tabled::{settings::Style, Table, Tabled}; #[derive(Tabled)] struct Library { #[tabled(rename = "Name")] name: String, #[tabled(rename = "Assets count")] assets_count: u32, #[tabled(display_with = "display_paths", rename = "Import paths")] import_paths: Vec, #[tabled(rename = "Updated at")] updated_at: DateTime, #[tabled(display_with = "display_option", rename = "Refreshed at")] refreshed_at: Option>, } pub async fn list_libraries(ctx: Context) -> Result<()> { let mut libraries: Vec<_> = FetchAllLibraries::new(()) .execute(&ctx) .await? .into_iter() .map(|library| Library { name: library.name, assets_count: library.asset_count as u32, import_paths: library.import_paths, updated_at: library.updated_at, refreshed_at: library.refreshed_at, }) .collect(); libraries.sort_by_key(|library| library.name.to_lowercase()); println!("{}", Table::new(libraries).with(Style::rounded()),); Ok(()) } fn display_option(o: &Option) -> String where T: Display, { match o { Some(s) => format!("{s}"), None => String::new(), } } fn display_paths(paths: &[String]) -> String { paths.join(", ") }