Compare commits
3 commits
94d771107d
...
f5180a559b
| Author | SHA1 | Date | |
|---|---|---|---|
| f5180a559b | |||
| 01d3755ea6 | |||
| 86845c54a6 |
10 changed files with 141 additions and 7 deletions
|
|
@ -10,8 +10,10 @@ pub enum QuestError {
|
||||||
IsNotAFile(PathBuf),
|
IsNotAFile(PathBuf),
|
||||||
/// std::io::Error happenned when loading
|
/// std::io::Error happenned when loading
|
||||||
IoError(std::io::Error),
|
IoError(std::io::Error),
|
||||||
|
/// toml::ser::Error happened when loading
|
||||||
|
TomlSerializeError(toml::ser::Error),
|
||||||
/// toml::de::Error happened when loading
|
/// toml::de::Error happened when loading
|
||||||
TomlError(toml::de::Error)
|
TomlDeserializeError(toml::de::Error),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for QuestError {
|
impl fmt::Display for QuestError {
|
||||||
|
|
@ -19,7 +21,8 @@ impl fmt::Display for QuestError {
|
||||||
match self {
|
match self {
|
||||||
QuestError::IsNotAFile(path) => write!(f, "{:?} is not a file", path),
|
QuestError::IsNotAFile(path) => write!(f, "{:?} is not a file", path),
|
||||||
QuestError::IoError(error) => write!(f, "io error: {error}"),
|
QuestError::IoError(error) => write!(f, "io error: {error}"),
|
||||||
QuestError::TomlError(error) => write!(f, "parse error: {error}")
|
QuestError::TomlSerializeError(error) => write!(f, "serialize error: {error}"),
|
||||||
|
QuestError::TomlDeserializeError(error) => write!(f, "parse error: {error}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
pub mod error;
|
pub mod error;
|
||||||
|
|
||||||
use std::path::PathBuf;
|
use std::{fs, io::Write, path::PathBuf};
|
||||||
|
|
||||||
use serde::{ Serialize, Deserialize };
|
use serde::{ Serialize, Deserialize };
|
||||||
use error::QuestError;
|
use error::QuestError;
|
||||||
|
|
@ -76,15 +76,104 @@ impl Default for Quest {
|
||||||
|
|
||||||
impl Quest {
|
impl Quest {
|
||||||
/// Parse quest TOML or return error
|
/// Parse quest TOML or return error
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
/// ```rust
|
||||||
|
/// use squad_quest::quest::{Quest,error::QuestError};
|
||||||
|
/// # fn main() {
|
||||||
|
/// # let _ = wrapper();
|
||||||
|
/// # }
|
||||||
|
///
|
||||||
|
/// # fn wrapper() -> Result<(), QuestError> {
|
||||||
|
/// let path = "quests/0.toml".into();
|
||||||
|
///
|
||||||
|
/// let quest = Quest::load(path)?;
|
||||||
|
/// #
|
||||||
|
/// # Ok(())
|
||||||
|
/// # }
|
||||||
|
/// ```
|
||||||
pub fn load(path: PathBuf) -> Result<Self, QuestError> {
|
pub fn load(path: PathBuf) -> Result<Self, QuestError> {
|
||||||
match std::fs::read_to_string(path) {
|
match std::fs::read_to_string(path) {
|
||||||
Ok(string) => {
|
Ok(string) => {
|
||||||
match toml::from_str::<Quest>(&string) {
|
match toml::from_str::<Quest>(&string) {
|
||||||
Ok(quest) => Ok(quest),
|
Ok(quest) => Ok(quest),
|
||||||
Err(error) => Err(QuestError::TomlError(error))
|
Err(error) => Err(QuestError::TomlDeserializeError(error))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Err(error) => Err(QuestError::IoError(error))
|
Err(error) => Err(QuestError::IoError(error))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Check if given file is a quest, then delete it or raise an error.
|
||||||
|
/// If file is not a quest, raises [QuestError::TomlDeserializeError]
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
/// ```rust
|
||||||
|
/// use squad_quest::quest::{Quest,error::QuestError};
|
||||||
|
///
|
||||||
|
/// let path = "quests/0.toml".into();
|
||||||
|
///
|
||||||
|
/// if let Err(error) = Quest::delete(path) {
|
||||||
|
/// // handle the error
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
pub fn delete(path: PathBuf) -> Result<(), QuestError> {
|
||||||
|
match Quest::load(path.clone()) {
|
||||||
|
Ok(_) => {
|
||||||
|
if let Err(error) = fs::remove_file(path) {
|
||||||
|
return Err(QuestError::IoError(error));
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
},
|
||||||
|
Err(error) => Err(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Save quest to given folder in TOML format.
|
||||||
|
/// File will be saved as `{id}.toml`.
|
||||||
|
/// If file exists, this method will override it.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
/// ```rust
|
||||||
|
/// # fn main() {
|
||||||
|
/// use squad_quest::quest::{Quest,error::QuestError};
|
||||||
|
/// use std::path::PathBuf;
|
||||||
|
///
|
||||||
|
/// let quest = Quest::default();
|
||||||
|
///
|
||||||
|
/// let path: PathBuf = "quests".into();
|
||||||
|
/// # let path2 = path.clone();
|
||||||
|
///
|
||||||
|
/// if let Err(error) = quest.save(path) {
|
||||||
|
/// // handle the error
|
||||||
|
/// }
|
||||||
|
/// # let filename = format!("{}.toml", quest.id);
|
||||||
|
/// # let _ = Quest::delete(path2.with_file_name(filename));
|
||||||
|
/// # }
|
||||||
|
/// ```
|
||||||
|
pub fn save(&self, path: PathBuf) -> Result<(), QuestError> {
|
||||||
|
let filename = format!("{}.toml", self.id);
|
||||||
|
let full_path = path.with_file_name(filename);
|
||||||
|
|
||||||
|
let str = match toml::to_string_pretty(&self) {
|
||||||
|
Ok(string) => string,
|
||||||
|
Err(error) => {
|
||||||
|
return Err(QuestError::TomlSerializeError(error));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut file = match fs::File::create(full_path) {
|
||||||
|
Ok(f) => f,
|
||||||
|
Err(error) => {
|
||||||
|
return Err(QuestError::IoError(error));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Err(error) = file.write_all(str.as_bytes()) {
|
||||||
|
return Err(QuestError::IoError(error));
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
29
tests/io.rs
Normal file
29
tests/io.rs
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
use squad_quest::{config::Config,quest::{error::{QuestError}, Quest}};
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
const CONFIG_PATH: &str = "tests/io/config.toml";
|
||||||
|
|
||||||
|
// Note: Quest::delete uses Quest::load underneath,
|
||||||
|
// and Quest::save can override files,
|
||||||
|
// so this test covers full quest CRUD
|
||||||
|
#[test]
|
||||||
|
fn quest_crud() -> Result<(), QuestError> {
|
||||||
|
let config = Config::load(CONFIG_PATH.into());
|
||||||
|
|
||||||
|
let mut quests_path = PathBuf::from(CONFIG_PATH).parent().unwrap().to_owned();
|
||||||
|
quests_path.push(config.quests_path);
|
||||||
|
|
||||||
|
let quest = Quest::default();
|
||||||
|
|
||||||
|
println!("{:?}", quests_path.clone());
|
||||||
|
|
||||||
|
quest.save(quests_path.clone())?;
|
||||||
|
|
||||||
|
let filename = format!("{}.toml", quest.id);
|
||||||
|
|
||||||
|
let delete_path = quests_path.with_file_name(filename);
|
||||||
|
|
||||||
|
Quest::delete(delete_path)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
1
tests/io/quests/.placeholder
Normal file
1
tests/io/quests/.placeholder
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
this file exists because git requires directory to have a file in order to commit it
|
||||||
|
|
@ -1,8 +1,10 @@
|
||||||
use squad_quest::{config::Config, quest::Quest};
|
use squad_quest::{config::Config, quest::Quest};
|
||||||
|
|
||||||
|
static CONFIG_PATH: &str = "./tests/main/config.toml";
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn load_quests() {
|
fn load_quests() {
|
||||||
let config = Config::load("./tests/cfg/config.toml".into());
|
let config = Config::load(CONFIG_PATH.into());
|
||||||
let quests = config.load_quests();
|
let quests = config.load_quests();
|
||||||
|
|
||||||
assert_eq!(quests.len(), 2);
|
assert_eq!(quests.len(), 2);
|
||||||
|
|
@ -11,7 +13,7 @@ fn load_quests() {
|
||||||
#[test]
|
#[test]
|
||||||
fn empty_quest_is_default() {
|
fn empty_quest_is_default() {
|
||||||
// First loaded quest should be 0.toml, which is empty
|
// First loaded quest should be 0.toml, which is empty
|
||||||
let config = Config::load("./tests/cfg/config.toml".into());
|
let config = Config::load(CONFIG_PATH.into());
|
||||||
let mut quests = config.load_quests();
|
let mut quests = config.load_quests();
|
||||||
quests.sort_by(|a,b| a.id.cmp(&b.id));
|
quests.sort_by(|a,b| a.id.cmp(&b.id));
|
||||||
let quest = quests.first().unwrap();
|
let quest = quests.first().unwrap();
|
||||||
|
|
@ -23,7 +25,7 @@ fn empty_quest_is_default() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn quest_one() {
|
fn quest_one() {
|
||||||
let config = Config::load("./tests/cfg/config.toml".into());
|
let config = Config::load(CONFIG_PATH.into());
|
||||||
let quests = config.load_quests();
|
let quests = config.load_quests();
|
||||||
let quest = quests.iter().find(|q| q.id == 1).unwrap();
|
let quest = quests.iter().find(|q| q.id == 1).unwrap();
|
||||||
|
|
||||||
|
|
|
||||||
10
tests/main/config.toml
Normal file
10
tests/main/config.toml
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
# Default config
|
||||||
|
|
||||||
|
# Path to quests folder relative to config
|
||||||
|
quests_path = "quests"
|
||||||
|
|
||||||
|
# Path to accounts folder relative to config
|
||||||
|
accounts_path = "accounts"
|
||||||
|
|
||||||
|
# Path to map .toml file relative to config
|
||||||
|
map = "map.toml"
|
||||||
Loading…
Add table
Add a link
Reference in a new issue