global: snapshot

This commit is contained in:
nym21
2024-12-13 19:55:32 +01:00
parent f6f4660cd2
commit 795791219e
315 changed files with 1931 additions and 4144 deletions
+139
View File
@@ -0,0 +1,139 @@
use std::{
fmt::Debug,
fs::{self, File},
io::{BufReader, BufWriter, Cursor},
path::Path,
};
use bincode::{
config, decode_from_slice, decode_from_std_read, encode_into_std_write, Decode, Encode,
};
use zstd::decode_all;
const ZST_EXTENSION: &str = "zst";
pub const BIN_EXTENSION: &str = "bin";
pub const COMPRESSED_BIN_EXTENSION: &str = "bin.zst";
enum BinaryType {
Raw,
Compressed,
}
pub struct Binary;
impl Binary {
pub fn import<T>(path: &Path) -> color_eyre::Result<T>
where
T: Decode,
{
match Self::type_from_path(path) {
BinaryType::Compressed => Self::import_compressed(path),
BinaryType::Raw => Self::import_raw(path),
}
}
fn import_raw<T>(path: &Path) -> color_eyre::Result<T>
where
T: Decode,
{
let config = config::standard();
let file = File::open(path)?;
let mut reader = BufReader::new(file);
let decoded = decode_from_std_read(&mut reader, config)?;
Ok(decoded)
}
fn import_compressed<T>(path: &Path) -> color_eyre::Result<T>
where
T: Decode,
{
let file = File::open(path).unwrap();
let reader = BufReader::new(file);
let decompressed = decode_all(reader).unwrap();
let config = config::standard();
let decoded = decode_from_slice::<T, _>(&decompressed, config)?.0;
Ok(decoded)
}
pub fn export<T>(path: &Path, value: &T) -> color_eyre::Result<()>
where
T: Debug + Encode,
{
// log(&format!("Exporting: {:?}", path));
match Self::type_from_path(path) {
BinaryType::Compressed => Self::export_compressed(path, value),
BinaryType::Raw => Self::export_raw(path, value),
}
}
fn export_raw<T>(path: &Path, value: &T) -> color_eyre::Result<()>
where
T: Debug + Encode,
{
let config = config::standard();
let file = File::create(path).inspect_err(|_| {
dbg!(path, value);
})?;
let mut writer = BufWriter::new(file);
encode_into_std_write(value, &mut writer, config)?;
Ok(())
}
fn export_compressed<T>(path: &Path, value: &T) -> color_eyre::Result<()>
where
T: Debug + Encode,
{
let config = config::standard();
let encoded = bincode::encode_to_vec(value, config).unwrap();
let cursor = Cursor::new(encoded);
let compressed = zstd::encode_all(cursor, 0).unwrap();
fs::write(path, compressed).unwrap();
Ok(())
}
pub fn has_correct_extension(path: &Path) -> bool {
let path = path.to_str().unwrap();
path.ends_with(BIN_EXTENSION) || path.ends_with(COMPRESSED_BIN_EXTENSION)
}
fn type_from_path(path: &Path) -> BinaryType {
let extension = path.extension();
if extension.is_none() {
panic!("Should have extension");
}
if !Self::has_correct_extension(path) {
dbg!(path);
panic!("Wrong extension")
}
let extension = extension.unwrap();
if extension == ZST_EXTENSION {
BinaryType::Compressed
} else {
BinaryType::Raw
}
}
}
+56
View File
@@ -0,0 +1,56 @@
use std::{
fs::File,
io::{BufReader, BufWriter},
path::Path,
};
use serde::{de::DeserializeOwned, Serialize};
pub struct Json;
pub const JSON_EXTENSION: &str = "json";
pub const HAR_EXTENSION: &str = "har";
impl Json {
pub fn import<T>(path: &Path) -> color_eyre::Result<T>
where
T: DeserializeOwned,
{
if !Self::has_correct_extension(path) {
panic!("Wrong extension");
}
let file = File::open(path)?;
let reader = BufReader::new(file);
Ok(serde_json::from_reader(reader)?)
}
pub fn export<T>(path: &Path, value: &T) -> color_eyre::Result<()>
where
T: Serialize,
{
if !Self::has_correct_extension(path) {
dbg!(path);
panic!("Wrong extension");
}
let file = File::create(path).unwrap_or_else(|_| {
dbg!(&path);
panic!("No such file or directory")
});
let mut writer = BufWriter::new(file);
serde_json::to_writer_pretty(&mut writer, value)?;
Ok(())
}
#[inline(always)]
pub fn has_correct_extension(path: &Path) -> bool {
let path = path.to_str().unwrap();
path.ends_with(JSON_EXTENSION) || path.ends_with(HAR_EXTENSION)
}
}
+7
View File
@@ -0,0 +1,7 @@
mod binary;
mod json;
mod serialization;
pub use binary::*;
pub use json::*;
pub use serialization::*;
+128
View File
@@ -0,0 +1,128 @@
use std::{
fmt::Debug,
fs,
path::{Path, PathBuf},
};
use allocative::Allocative;
use bincode::{Decode, Encode};
use color_eyre::eyre::eyre;
use serde::{de::DeserializeOwned, Serialize};
use crate::io::{Binary, Json};
use super::{BIN_EXTENSION, COMPRESSED_BIN_EXTENSION, HAR_EXTENSION, JSON_EXTENSION};
#[derive(PartialEq, PartialOrd, Ord, Eq, Debug, Clone, Copy, Default, Allocative)]
pub enum Serialization {
#[default]
Binary,
Json,
}
impl Serialization {
pub fn is_serializable(&self, path: &Path) -> bool {
let path = path.to_str().unwrap();
match self {
Self::Binary => {
path.ends_with(BIN_EXTENSION) || path.ends_with(COMPRESSED_BIN_EXTENSION)
}
Self::Json => path.ends_with(JSON_EXTENSION) || path.ends_with(HAR_EXTENSION),
}
}
pub fn import<T>(&self, path: &Path) -> color_eyre::Result<T>
where
T: Debug + DeserializeOwned + Decode,
{
match self {
Serialization::Binary => {
if self.is_serializable(path) {
Binary::import(path)
} else {
let path = path.to_str().unwrap();
let bin_path_str = format!("{path}.{BIN_EXTENSION}");
let bin_path = Path::new(&bin_path_str);
if bin_path.exists() {
return Binary::import(bin_path);
}
let compressed_bin_path_str = format!("{path}.{COMPRESSED_BIN_EXTENSION}");
let compressed_bin_path = Path::new(&compressed_bin_path_str);
if compressed_bin_path.exists() {
return Binary::import(compressed_bin_path);
}
Err(eyre!("Wrong path or no file"))
}
}
Serialization::Json => {
if self.is_serializable(path) {
Json::import(path)
} else {
let path = path.to_str().unwrap();
let json_path_str = format!("{path}.{JSON_EXTENSION}");
let json_path = Path::new(&json_path_str);
if json_path.exists() {
return Json::import(json_path);
}
Err(eyre!("Wrong path or no file"))
}
}
}
}
pub fn export<T>(&self, path: &Path, value: &T) -> color_eyre::Result<()>
where
T: Debug + Serialize + Encode,
{
match self {
Serialization::Binary => {
if self.is_serializable(path) {
Binary::export(path, value)
} else {
let path = path.to_str().unwrap();
let res = Binary::export(
Path::new(&format!("{}.{COMPRESSED_BIN_EXTENSION}", path)),
value,
);
if res.is_ok() {
let _ = fs::remove_file(Path::new(&format!("{}.{BIN_EXTENSION}", path)));
}
res
}
}
Serialization::Json => {
if self.is_serializable(path) {
Json::export(path, value)
} else {
Json::export(
Path::new(&format!("{}.{JSON_EXTENSION}", path.to_str().unwrap())),
value,
)
}
}
}
}
}
impl TryFrom<&PathBuf> for Serialization {
type Error = ();
fn try_from(path: &PathBuf) -> Result<Self, Self::Error> {
let extension = path.extension().ok_or(())?.to_str().unwrap();
match extension {
BIN_EXTENSION | COMPRESSED_BIN_EXTENSION => Ok(Self::Binary),
JSON_EXTENSION => Ok(Self::Json),
_ => Err(()),
}
}
}