#![doc = include_str!("../README.md")]
#![warn(missing_docs)]
use std::path::PathBuf;
use serde::{Deserialize, Serialize};
use crate::{
error::Error,
secure::{KeyStore, PlatformKeyStore},
};
pub mod error;
pub mod secure;
pub trait GlobalByteBox<const SECURE: bool>: Serialize + for<'de> Deserialize<'de> {
fn path() -> PathBuf;
fn save(&self) -> Result<(), Error> {
let path = Self::path();
let bytes = self.encode()?;
std::fs::write(&path, bytes)?;
Ok(())
}
fn load() -> Result<Self, Error>
where
Self: Sized,
{
let path = Self::path();
let bytes = std::fs::read(&path)?;
Self::decode(&bytes)
}
fn encode(&self) -> Result<Vec<u8>, Error> {
if SECURE {
let name = format!("{}", Self::path().display());
let bytes = bitcode::serialize(self)?;
let key = PlatformKeyStore::get_key_or_generate(&name)?;
secure::encrypt(&bytes, key)
} else {
Ok(bitcode::serialize(self)?)
}
}
fn decode(bytes: &[u8]) -> Result<Self, Error> {
if SECURE {
let name = Self::path().to_string_lossy().to_string();
let key = PlatformKeyStore::get_key_or_generate(&name)?;
let decrypted = secure::decrypt(bytes.to_vec(), key)?;
Ok(bitcode::deserialize(&decrypted)?)
} else {
Ok(bitcode::deserialize(bytes)?)
}
}
}
pub trait ByteBox<const SECURE: bool>: Serialize + for<'de> Deserialize<'de> {
fn path(&self) -> PathBuf;
fn save(&self) -> Result<(), Error> {
let path = self.path();
let bytes = self.encode()?;
std::fs::write(&path, bytes)?;
Ok(())
}
fn load(&mut self) -> Result<(), Error> {
let path = self.path();
let bytes = std::fs::read(&path)?;
*self = self.decode(&bytes)?;
Ok(())
}
fn encode(&self) -> Result<Vec<u8>, Error> {
if SECURE {
let name = format!("{}", self.path().display());
let bytes = bitcode::serialize(self)?;
let key = PlatformKeyStore::get_key_or_generate(&name)?;
secure::encrypt(&bytes, key)
} else {
Ok(bitcode::serialize(self)?)
}
}
fn decode(&self, bytes: &[u8]) -> Result<Self, Error> {
if SECURE {
let name = format!("{}", self.path().display());
let key = PlatformKeyStore::get_key_or_generate(&name)?;
let decrypted = secure::decrypt(bytes.to_vec(), key)?;
Ok(bitcode::deserialize(&decrypted)?)
} else {
Ok(bitcode::deserialize(bytes)?)
}
}
}