feat!: Account features

- 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
This commit is contained in:
Alexey 2025-12-02 14:33:38 +03:00
commit 0e8cdde697
12 changed files with 285 additions and 98 deletions

View file

@ -1,24 +1,97 @@
//! User accounts
use std::{fs, io::Write, path::PathBuf};
use serde::{ Serialize, Deserialize };
use crate::{SquadObject, error::Error};
fn default_id() -> String {
"none".to_string()
}
/// User account struct, which can be (de-)serialized from/into TOML
#[derive(Serialize, Deserialize)]
#[derive(Serialize, Deserialize, PartialEq, Debug)]
#[serde(default)]
pub struct Account {
/// User identifier, specific to used service
#[serde(default = "default_id")]
pub id: String,
/// User balance
#[serde(default)]
pub balance: u32,
/// Id of room node where user is located
#[serde(default)]
pub location: u16
pub location: u16,
/// Vec of quests completed by this user
pub quests_completed: Vec<u16>,
/// Vec of rooms unlocked by this user
pub rooms_unlocked: Vec<u16>,
}
impl Default for Account {
fn default() -> Self {
Account {
id: default_id(),
balance: u32::default(),
location: u16::default(),
quests_completed: Vec::new(),
rooms_unlocked: Vec::new(),
}
}
}
impl SquadObject for Account {
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 Self::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(())
}
}