use crate::{generate_keys, ClientKey, Config, ServerKey};
use std::fs::File;
use std::io::{BufReader, BufWriter};
use std::path::PathBuf;
#[cfg_attr(doc, cfg(feature = "serde"))]
pub struct KeyCacher<SF, DF> {
path: PathBuf,
config: Config,
serialize_func: SF,
deserialize_func: DF,
}
impl<SerFn, DeFn> KeyCacher<SerFn, DeFn> {
pub fn new<P: Into<PathBuf>>(
path: P,
config: Config,
serialize_func: SerFn,
deserialize_func: DeFn,
) -> Self {
Self {
path: path.into(),
config,
serialize_func,
deserialize_func,
}
}
}
impl<SerFn, DeFn, E> KeyCacher<SerFn, DeFn>
where
E: std::fmt::Debug,
SerFn: Fn(BufWriter<File>, &(ClientKey, ServerKey)) -> Result<(), E>,
DeFn: Fn(BufReader<File>) -> Result<(ClientKey, ServerKey), E>,
{
pub fn get(&self) -> (ClientKey, ServerKey) {
let maybe_keys = if self.path.exists() {
File::open(&self.path)
.ok()
.map(BufReader::new)
.and_then(|file| (self.deserialize_func)(file).ok())
} else {
None
};
match maybe_keys {
Some(keys) => keys,
None => {
let keys = generate_keys(self.config.clone());
let output_file = File::create(&self.path).map(BufWriter::new).unwrap();
(self.serialize_func)(output_file, &keys).unwrap();
keys
}
}
}
}