use std::{
error::Error,
fs::{read_to_string, OpenOptions},
io::Write,
path::{Path, PathBuf},
};
use serde::{de::DeserializeOwned, Serialize};
use tracing;
use crate::utils::misc::create_path;
pub trait Load
where
Self: Sized + DeserializeOwned,
{
fn load(path: impl Into<PathBuf>) -> Self {
let contents = read_to_string(path.into()).unwrap();
let deserialized: Self = serde_json::from_str(&contents).unwrap();
deserialized
}
}
pub trait Save
where
Self: Serialize,
{
fn save(&self, path: &str) -> Result<String, Box<dyn Error>> {
create_path(path, true)?;
tracing::trace!(path = path, "Attempting JSON serialization");
let serialized = match serde_json::to_string_pretty(&self) {
Ok(s) => s,
Err(e) => {
tracing::error!(path = path, error = %e, "JSON serialization failed");
return Err(e.into());
}
};
tracing::trace!(
path = path,
bytes = serialized.len(),
"Serialization successful"
);
let mut file = OpenOptions::new()
.write(true)
.create(true)
.truncate(true)
.open(Path::new(path))?;
file.write_all(serialized.as_bytes())?;
Ok(serialized)
}
}
pub trait Reproduce: Load + Save {}
impl<T> Load for T where T: Sized + DeserializeOwned {}
impl<T> Save for T where T: Serialize {}
impl<T> Reproduce for T where T: Load + Save {}