- Bump version to 0.2.0
- Added trait SquadObject
- Implemented SquadObject for Quest and Account
- Implemented Config::load_accounts
- Removed src/quest/error.rs
- Added account tests in tests/main.rs
BREAKING CHANGE: Quest::{load,delete,save} are now provided by
SquadObject trait
139 lines
3.3 KiB
Rust
139 lines
3.3 KiB
Rust
//! 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<Date>,
|
|
|
|
/// When quest expires
|
|
pub deadline: Option<Date>
|
|
}
|
|
|
|
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<Self, Error> {
|
|
match std::fs::read_to_string(path) {
|
|
Ok(string) => {
|
|
match toml::from_str::<Self>(&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(())
|
|
}
|
|
}
|