use std::fs::{create_dir_all, File};
use std::io::{Read, Write};
use std::panic;
use std::path::PathBuf;
use ron::de::from_str;
use serde::de::DeserializeOwned;
pub trait Container {
fn get_file_name(&self) -> &str;
fn get_file_path(&self) -> &PathBuf;
}
pub trait Fetchable {
fn deserialize_l<T: DeserializeOwned + Default + Fetchable>(
f_path: &PathBuf,
) -> std::io::Result<T>;
fn deserialize_bin<T: DeserializeOwned + Default>(f_path: &PathBuf) -> std::io::Result<T> {
match File::open(f_path) {
Ok(mut f) => {
let mut buffer = Vec::new();
f.read_to_end(&mut buffer)?;
let item: T = match bincode::deserialize(&buffer) {
Ok(item) => item,
Err(_e) => T::default(),
};
buffer.clear();
Ok(item)
}
Err(e) => panic!("Failed to deserialize requested object: {:?}", e),
}
}
fn deserialize_ron<T: DeserializeOwned + Default>(f_path: &PathBuf) -> std::io::Result<T> {
match File::open(f_path) {
Ok(mut f) => {
let mut buffer = String::new();
f.read_to_string(&mut buffer)?;
let item: T = match from_str(&buffer) {
Ok(item) => item,
Err(_e) => T::default(),
};
Ok(item)
}
Err(e) => panic!("Failed to deserialize requested object: {:?}", e),
}
}
fn serialize_l(&self) -> std::io::Result<Vec<u8>>
where
Self: serde::Serialize + Fetchable;
fn serialize_bin(&self) -> std::io::Result<Vec<u8>>
where
Self: serde::Serialize,
{
let mut buf = vec![];
buf.clear();
buf = match bincode::serialize(self) {
Ok(b) => b,
Err(e) => panic!("Could not serialize: {:?}", e),
};
Ok(buf)
}
fn serialize_ron(&self) -> std::io::Result<Vec<u8>>
where
Self: serde::Serialize,
{
Ok(
ron::ser::to_string_pretty(&self, ron::ser::PrettyConfig::default())
.expect("Failed pretty string.")
.as_bytes()
.to_vec(),
)
}
fn save(&self) -> std::io::Result<()>
where
Self: serde::Serialize + Container + Fetchable,
{
let mut path = self.get_file_path().to_path_buf();
path.push(self.get_file_name());
let mut f = File::create(path)?;
let content = self.serialize_l()?; f.write_all(content.as_slice())?;
f.sync_all()
}
fn save_x(&self, tag: &str, file_name: &str, path: &PathBuf) -> std::io::Result<()>
where
Self: serde::Serialize + Fetchable,
{
let mut path = path.to_path_buf();
path.push(tag);
if !path.exists() {
create_dir_all(&path)?;
}
path.push(file_name);
let mut f = File::create(&path)?;
let content = self.serialize_l()?; f.write_all(content.as_slice())?;
f.sync_all()
}
fn save_y(&self, path: &PathBuf) -> std::io::Result<()>
where
Self: serde::Serialize + Fetchable,
{
let mut f = File::create(&path)?;
let content = self.serialize_l()?;
f.write_all(content.as_slice())?;
f.sync_all()
}
fn fetch<T: Default + DeserializeOwned + Fetchable>(
tag: &str,
file_name: &str,
file_path: &PathBuf,
) -> std::io::Result<T> {
let mut path = file_path.to_path_buf();
path.push(tag);
path.push(file_name);
let result: T = if path.exists() {
match T::deserialize_l(&path) {
Ok(t) => t,
Err(_) => T::default(),
}
} else {
T::default()
};
Ok(result)
}
fn fetch_or_default<T: Default + DeserializeOwned + Fetchable>(
file_path: &PathBuf,
) -> std::io::Result<(T, bool)> {
let path = file_path.to_path_buf();
let result: (T, bool) = if path.exists() {
match T::deserialize_l(&path) {
Ok(t) => (t, false),
Err(_) => (T::default(), true),
}
} else {
(T::default(), true)
};
Ok(result)
}
fn fetch_self(&self) -> Self
where
Self: Default + DeserializeOwned + Fetchable + Container,
{
let mut path = self.get_file_path().to_path_buf();
path.push(self.get_file_name());
let res: Self = match Self::deserialize_l(&path) {
Ok(r) => r,
Err(_e) => Self::default(),
};
res
}
}