//! Text-based quests and user solutions for them use std::{fs, io::Write, path::PathBuf}; use serde::{ Serialize, Deserialize }; use crate::{SquadObject, error::Error}; use toml::value::Date; /// Difficulty of the quest #[derive(Serialize, Deserialize, Debug, PartialEq, Clone, Copy)] pub enum QuestDifficulty { /// Easy quest Easy, /// Normal quest Normal, /// Hard quest Hard, /// Special case of hard quests. Also is a default value for enum Secret } impl Default for QuestDifficulty { fn default() -> Self { QuestDifficulty::Secret } } fn default_name() -> String { "Slay the dragon".to_string() } fn default_description() -> String { "Just do it in any way".to_string() } fn default_answer() -> String { "Attachment should show that the dragon was slain".to_string() } /// Quest struct #[derive(Serialize, Deserialize, Debug, PartialEq)] #[serde(default)] pub struct Quest { /// Quest identifier pub id: u16, /// Difficulty of this quest pub difficulty: QuestDifficulty, /// Reward for the quest pub reward: u32, /// Visible quest name pub name: String, /// Visible quest description pub description: String, /// Quest answer, available for admins pub answer: String, /// Is quest available for regular users pub public: bool, /// When quest becomes public pub available_on: Option, /// When quest expires pub deadline: Option } impl Default for Quest { fn default() -> Self { Quest { id: u16::default(), difficulty: QuestDifficulty::default(), reward: u32::default(), name: default_name(), description: default_description(), answer: default_answer(), public: false, available_on: None, deadline: None } } } impl SquadObject for Quest { fn load(path: PathBuf) -> Result { match std::fs::read_to_string(path) { Ok(string) => { match toml::from_str::(&string) { Ok(object) => Ok(object), Err(error) => Err(Error::TomlDeserializeError(error)) } }, Err(error) => Err(Error::IoError(error)) } } fn delete(path: PathBuf) -> Result<(), Error> { match Quest::load(path.clone()) { Ok(_) => { if let Err(error) = fs::remove_file(path) { return Err(Error::IoError(error)); } Ok(()) }, Err(error) => Err(error) } } fn save(&self, path: PathBuf) -> Result<(), Error> { let filename = format!("{}.toml", self.id); let mut full_path = path; full_path.push(filename); let str = match toml::to_string_pretty(&self) { Ok(string) => string, Err(error) => { return Err(Error::TomlSerializeError(error)); } }; let mut file = match fs::File::create(full_path) { Ok(f) => f, Err(error) => { return Err(Error::IoError(error)); } }; if let Err(error) = file.write_all(str.as_bytes()) { return Err(Error::IoError(error)); } Ok(()) } }