marble-machinations/src/solution.rs

76 lines
1.6 KiB
Rust

use std::{
fs::{self, File},
io::Write,
path::PathBuf,
};
use serde::{Deserialize, Serialize};
use crate::{level::Level, userdata_dir};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Solution {
solution_id: usize,
level_id: String,
pub name: String,
pub board: String,
#[serde(default)]
pub score: Option<Score>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Score {
pub cycles: usize,
pub tiles: usize,
}
impl Solution {
pub fn new(level: &Level, id: usize) -> Self {
Self {
solution_id: id,
level_id: level.id().to_owned(),
name: format!("Unnamed {id}"),
board: level.init_board().unwrap_or(String::from(" ")),
score: None,
}
}
pub fn new_copy(&self, id: usize) -> Self {
let mut new = self.clone();
new.solution_id = id;
new.score = None;
new
}
pub fn id(&self) -> usize {
self.solution_id
}
fn path(&self) -> PathBuf {
let dir = userdata_dir().join("solutions").join(&self.level_id);
fs::create_dir_all(&dir).unwrap();
dir.join(format!("solution_{}.json", &self.solution_id))
}
pub fn save(&self) {
let path = self.path();
let json = serde_json::to_string_pretty(self).unwrap();
let mut file = File::create(path).unwrap();
file.write_all(json.as_bytes()).unwrap();
}
pub fn remove_file(&self) {
let path = self.path();
if let Err(e) = fs::remove_file(path) {
eprint!("Error removing solution file: {e}");
}
}
pub fn score_text(&self) -> String {
if let Some(score) = &self.score {
format!("C: {} T: {}", score.cycles, score.tiles)
} else {
"unsolved".into()
}
}
}