use std::{io::{stdin, stdout, Read, Write}, fs::{File, create_dir_all, self, OpenOptions}};
use anyhow::Context;
use sodiumoxide::crypto::box_::{PublicKey, SecretKey};
use crate::base62;
pub fn open_input(input: Option<String>) -> anyhow::Result<Box<dyn Read>> {
if let Some(filename) = input {
Ok(Box::new(File::open(&filename)
.context(format!("unable to open '{filename}' for input"))?))
} else {
Ok(Box::new(stdin()))
}
}
pub fn open_output(output: Option<String>) -> anyhow::Result<Box<dyn Write>> {
if let Some(filename) = output {
Ok(Box::new(
OpenOptions::new()
.write(true)
.create_new(true)
.open(&filename)
.context(format!("unable to open '{filename}' for output"))?
))
} else {
Ok(Box::new(stdout()))
}
}
pub fn open_or_create_key_directory(path: &str) -> anyhow::Result<()> {
create_dir_all(&path)
.context(format!("unable to open/create {path}'"))
}
pub fn key_path(keydir: &str, b62_pkey: &str) -> String {
format!("{keydir}/{b62_pkey}.secret") }
pub fn disk_lookup(keydir: &str, target_pkey: &PublicKey) -> anyhow::Result<SecretKey> {
let path = key_path(keydir, &base62::encode(&target_pkey.0));
let b62_skey = fs::read_to_string(path)?;
Ok(SecretKey(base62::decode(&b62_skey)?))
}