use anyhow::{Result, bail};
use serde::Serialize;
use smartpasslib::SmartPasswordManager;
use crate::clipboard;
use crate::output;
use crate::qr;
use crate::secret;
use super::find_entry;
#[derive(Serialize)]
struct GetJson<'a> {
description: &'a str,
public_key: &'a str,
length: usize,
password: &'a str,
}
pub fn run(
key: Option<String>,
description: Option<String>,
secret_arg: Option<String>,
secret_stdin: bool,
copy: bool,
qr_flag: bool,
json: bool,
) -> Result<()> {
let manager = SmartPasswordManager::new()?;
let entry = find_entry(&manager, key, description)?;
let secret_phrase = secret::resolve_secret(secret_arg, secret_stdin, "Secret phrase: ")?;
let valid = smartpasslib::verify_secret(&secret_phrase, &entry.public_key)?;
if !valid {
bail!("Wrong secret phrase");
}
let password = smartpasslib::generate_smart_password_sync(&secret_phrase, entry.length)?;
if qr_flag {
qr::render(&password);
return Ok(());
}
if copy {
if clipboard::copy(&password) {
output::success(&format!(
"Password for '{}' copied to clipboard",
entry.description
));
} else {
bail!("No clipboard available");
}
return Ok(());
}
if json {
let obj = GetJson {
description: &entry.description,
public_key: &entry.public_key,
length: entry.length,
password: &password,
};
let s = serde_json::to_string_pretty(&obj)?;
println!("{s}");
} else {
output::print_password(&password);
}
Ok(())
}