save-sync/src/game.rs

90 lines
1.9 KiB
Rust

use std::fs::File;
use std::hash::Hasher;
use std::io::{Read, Write};
use std::path::{Path, PathBuf};
use thiserror::Error;
use twox_hash::XxHash64;
use uuid::Uuid;
// TODO: Change this seed
const XXHASH64_SEED: u64 = 1337;
#[derive(Debug, Clone)]
pub struct GameSaveLocation {
pub friendly_name: Option<String>,
files: Vec<GameFile>,
uuid: Uuid,
}
impl GameSaveLocation {
pub fn new(files: Vec<GameFile>, friendly_name: Option<String>) -> Self {
Self {
friendly_name,
files,
uuid: Uuid::new_v4(),
}
}
}
#[derive(Debug, Clone)]
pub struct GameFile {
pub original_path: PathBuf,
pub hash: u64,
}
impl GameFile {
pub fn new<P: AsRef<Path>>(path: P) -> std::io::Result<Self> {
let path = path.as_ref();
let file = File::open(path)?;
Ok(Self {
original_path: path.to_path_buf(),
hash: Self::calculate_hash(file)?,
})
}
fn calculate_hash(mut buf: impl Read) -> std::io::Result<u64> {
let mut hash_writer = HashWriter(XxHash64::with_seed(XXHASH64_SEED));
std::io::copy(&mut buf, &mut hash_writer)?;
Ok(hash_writer.0.finish())
}
}
#[derive(Error, Debug)]
pub enum GameFileError {
#[error(transparent)]
IOError(#[from] std::io::Error),
}
#[derive(Debug, Default)]
pub struct BackupPath {
inner: Option<PathBuf>,
}
impl BackupPath {
pub fn new<P: AsRef<Path>>(path: P) -> Self {
Self {
inner: Some(path.as_ref().to_path_buf()),
}
}
}
impl BackupPath {}
struct HashWriter<T: Hasher>(T);
impl<T: Hasher> Write for HashWriter<T> {
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
self.0.write(buf);
Ok(buf.len())
}
fn flush(&mut self) -> std::io::Result<()> {
Ok(())
}
fn write_all(&mut self, buf: &[u8]) -> std::io::Result<()> {
self.write(buf).map(|_| ())
}
}