use anyhow::Result;
use serde::Serialize;
use smartpasslib::{SmartPassword, SmartPasswordManager};
use crate::output;
use super::short_key;
#[derive(Serialize)]
struct ListJson<'a> {
description: &'a str,
public_key: &'a str,
length: usize,
}
pub fn run(json: bool) -> Result<()> {
let manager = SmartPasswordManager::new()?;
let mut entries: Vec<&SmartPassword> = manager.passwords().values().collect();
entries.sort_by(|a, b| {
a.description
.to_lowercase()
.cmp(&b.description.to_lowercase())
});
if json {
let list: Vec<ListJson> = entries
.iter()
.map(|e| ListJson {
description: &e.description,
public_key: &e.public_key,
length: e.length,
})
.collect();
let s = serde_json::to_string_pretty(&list)?;
println!("{s}");
return Ok(());
}
if entries.is_empty() {
output::note("No entries.");
return Ok(());
}
let max_desc = entries
.iter()
.map(|e| e.description.chars().count())
.max()
.unwrap_or(20)
.min(60);
for entry in entries {
let desc = pad_right(&entry.description, max_desc);
println!(
"{desc} {:>3} chars {}",
entry.length,
short_key(&entry.public_key)
);
}
Ok(())
}
fn pad_right(s: &str, width: usize) -> String {
let count = s.chars().count();
if count >= width {
return s.chars().take(width).collect();
}
let mut out = s.to_string();
for _ in count..width {
out.push(' ');
}
out
}