#![allow(unused)] use crate::Result;
use crossterm::cursor::MoveTo;
use crossterm::terminal::ClearType;
use crossterm::{execute, terminal};
use keyring::Entry;
use std::io::{self, Write};
const KEY_SERVICE: &str = "aipack_secrets";
fn _clear_api_key(key_name: &str) -> Result<()> {
_clear_key(KEY_SERVICE, key_name)?;
Ok(())
}
pub fn get_or_prompt_api_key(key_name: &str) -> Result<String> {
let api_key = get_and_save_pwd(KEY_SERVICE, key_name)?;
Ok(api_key)
}
fn get_and_save_pwd(service: &str, name: &str) -> Result<String> {
let entry = Entry::new(service, name)?;
let pwd = match entry.get_password() {
Ok(pwd) => pwd,
Err(keyring::Error::NoEntry) => prompt_and_save(entry, name)?,
Err(other) => return Err(format!("Failed to execute keyring: {other}").into()),
};
Ok(pwd)
}
fn _clear_key(service: &str, name: &str) -> Result<bool> {
if let Ok(entry) = Entry::new(service, name) {
entry.delete_credential()?;
Ok(true)
} else {
Ok(false)
}
}
fn prompt_and_save(entry: Entry, disp_name: &str) -> Result<String> {
terminal::disable_raw_mode().expect("Failed to disable crossterm raw mode");
print!(
r#"
API KEY for '{}' not found in environment vairable or keychain
Please enter value (will store key in Mac keychain, under aipack_secrets/{}):
"#,
disp_name, disp_name
);
io::stdout().flush()?;
let mut input = String::new();
io::stdin().read_line(&mut input)?;
let val = input.trim().to_string();
if val.is_empty() {
return Err("Value cannot be empty.".into());
}
entry.set_password(&val)?;
let val = entry.get_password()?;
clear_terminal()?;
std::thread::sleep(std::time::Duration::from_millis(200));
terminal::enable_raw_mode().expect("Failed to enable crossterm raw mode");
Ok(val)
}
fn clear_terminal() -> Result<()> {
let mut stdout = io::stdout();
execute!(stdout, terminal::Clear(ClearType::All))?;
execute!(stdout, MoveTo(0, 0))?; Ok(())
}