werewolves/werewolves-server/src/saver.rs

65 lines
2.0 KiB
Rust

// Copyright (C) 2025-2026 Emilis Bliūdžius
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
use core::fmt::Display;
use std::{io::Write, path::PathBuf};
use thiserror::Error;
use werewolves_proto::game::Game;
pub trait Saver: Clone + Send + 'static {
type Error: Display;
fn save(&mut self, game: &Game) -> Result<String, Self::Error>;
}
#[derive(Debug, Error)]
pub enum FileSaverError {
#[error("io error: {0}")]
IoError(std::io::Error),
#[error("serialization error: {0}")]
SerializationError(#[from] ron::Error),
}
impl From<std::io::Error> for FileSaverError {
fn from(value: std::io::Error) -> Self {
Self::IoError(value)
}
}
#[derive(Debug, Clone)]
pub struct FileSaver {
path: PathBuf,
}
impl FileSaver {
pub const fn new(path: PathBuf) -> Self {
Self { path }
}
}
impl Saver for FileSaver {
type Error = FileSaverError;
fn save(&mut self, game: &Game) -> Result<String, Self::Error> {
let name = format!("werewolves_{}.ron", chrono::Utc::now().timestamp());
let path = self.path.join(name.clone());
let mut file = std::fs::File::create_new(path.clone())?;
// serde_json::to_writer_pretty(&mut file, &game)?;
ron::ser::to_writer_pretty(&mut file, &game.story(), ron::ser::PrettyConfig::new())?;
file.flush()?;
Ok(path.to_str().map(|s| s.to_string()).unwrap_or(name))
}
}