use std::fmt;
use std::path::{Path, PathBuf};
use std::str::FromStr;
use crate::{IV_SIZE, SALT_SIZE};
pub trait Secure {
fn path(&self) -> &WalletPath;
fn aes_key(&self) -> &[u8];
fn zeroize_aes_key(&mut self);
fn salt(&self) -> Option<&[u8; SALT_SIZE]>;
fn iv(&self) -> Option<&[u8; IV_SIZE]>;
}
#[derive(PartialEq, Eq, Hash, Debug, Clone)]
pub struct WalletPath {
pub wallet: PathBuf,
pub profile_dir: PathBuf,
pub network: Option<String>,
}
impl WalletPath {
#[must_use]
pub fn new(wallet: &Path) -> Self {
let wallet = wallet.to_path_buf();
let mut profile_dir = wallet.clone();
profile_dir.pop();
Self {
wallet,
profile_dir,
network: None,
}
}
#[must_use]
pub fn name(&self) -> Option<String> {
let name = self.wallet.file_stem()?.to_str()?;
Some(String::from(name))
}
pub fn dir(&self) -> Option<PathBuf> {
self.wallet.parent().map(PathBuf::from)
}
#[must_use]
pub fn inner(&self) -> &PathBuf {
&self.wallet
}
pub fn set_network_name(&mut self, network: Option<String>) {
self.network = network;
}
#[must_use]
pub fn cache_dir(&self) -> PathBuf {
let mut cache = self.profile_dir.clone();
if let Some(network) = &self.network {
cache.push(format!("cache_{network}"));
} else {
cache.push("cache");
}
cache
}
}
impl FromStr for WalletPath {
type Err = crate::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let p = Path::new(s);
Ok(Self::new(p))
}
}
impl From<PathBuf> for WalletPath {
fn from(p: PathBuf) -> Self {
Self::new(&p)
}
}
impl From<&Path> for WalletPath {
fn from(p: &Path) -> Self {
Self::new(p)
}
}
impl fmt::Display for WalletPath {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"wallet path: {}\n\rprofile dir: {}\n\rnetwork: {}",
self.wallet.display(),
self.profile_dir.display(),
self.network.as_ref().unwrap_or(&"default".to_string())
)
}
}