diff --git a/src/bin/cli.rs b/src/bin/cli.rs index 545b656..fef2fc1 100644 --- a/src/bin/cli.rs +++ b/src/bin/cli.rs @@ -1,6 +1,7 @@ use std::path::PathBuf; use clap::{Parser,Subcommand,Args,ValueEnum}; +use squad_quest::{config::Config,quest::{Quest,QuestDifficulty as LibQuestDifficulty}}; #[derive(Parser)] #[command(version, about, long_about = None)] @@ -33,6 +34,17 @@ enum QuestDifficulty { Secret } +impl From for LibQuestDifficulty { + fn from(value: QuestDifficulty) -> Self { + match value { + QuestDifficulty::Easy => LibQuestDifficulty::Easy, + QuestDifficulty::Normal => LibQuestDifficulty::Normal, + QuestDifficulty::Hard => LibQuestDifficulty::Hard, + QuestDifficulty::Secret => LibQuestDifficulty::Secret, + } + } +} + #[derive(Subcommand)] enum QuestCommands { /// List available quests @@ -72,16 +84,20 @@ struct QuestUpdateArgs { /// Id of the quest to update id: u16, /// Difficulty of the quest - #[arg(value_enum)] - difficulty: QuestDifficulty, + #[arg(value_enum,long)] + difficulty: Option, /// Reward for the quest - reward: u32, + #[arg(long)] + reward: Option, /// Name of the quest - name: String, + #[arg(long)] + name: Option, /// Visible description of the quest - description: String, + #[arg(long)] + description: Option, /// Answer for the quest for admins - answer: String + #[arg(long)] + answer: Option } #[derive(Args)] @@ -90,6 +106,105 @@ struct QuestDeleteArgs { id: u16 } -fn main() { - let _cli = Cli::parse(); +fn print_quest_short(quest: &Quest) { + println!("Quest #{}: {}", quest.id, quest.name); +} + +fn print_quest_long(quest: &Quest) { + print_quest_short(quest); + println!("Difficulty: {:?}", quest.difficulty); + println!("Description:\n{}", quest.description); + println!("Answer:\n{}", quest.answer); +} + +fn main() { + let cli = Cli::parse(); + + let config = Config::load(cli.config.clone()); + + match &cli.command { + Objects::Quest(commands) => { + match commands { + QuestCommands::List(args) => { + let quests = config.load_quests(); + for quest in quests { + if args.short { + print_quest_short(&quest); + } else { + print_quest_long(&quest); + } + } + }, + QuestCommands::Create(args) => { + let mut quests = config.load_quests(); + quests.sort_by(|a,b| a.id.cmp(&b.id)); + let next_id = match quests.last() { + Some(quest) if quest.id == u16::MAX => { + panic!("Error: quest list contains quest with u16::MAX id."); + } + Some(quest) => quest.id + 1u16, + None => 0u16 + }; + + let path = config.full_quests_path(); + let mut quest_path = path.clone(); + quest_path.push(format!("{next_id}.toml")); + match std::fs::exists(&quest_path) { + Ok(exists) => { + if exists { + panic!("Error: {:?} is not empty.", quest_path); + } + }, + Err(error) => { + panic!("Error while retrieving {:?}: {}.", quest_path, error); + } + } + + let quest = Quest { + id: next_id, + difficulty: args.difficulty.into(), + reward: args.reward, + name: args.name.clone(), + description: args.description.clone(), + answer: args.answer.clone(), + }; + if let Err(error) = quest.save(path) { + eprintln!("Error while saving quest: {error}."); + } else { + println!("Successfully saved quest #{}.", quest.id); + } + }, + QuestCommands::Update(args) => { + let quests = config.load_quests(); + let Some(quest) = quests.iter().find(|q| q.id == args.id) else { + panic!("Error: Quest #{} not found.", args.id); + }; + let quest = Quest { + id: args.id, + difficulty: match args.difficulty { + Some(diff) => diff.into(), + None => quest.difficulty + }, + reward: args.reward.unwrap_or(quest.reward), + name: args.name.clone().unwrap_or(quest.name.clone()), + description: args.description.clone().unwrap_or(quest.description.clone()), + answer: args.answer.clone().unwrap_or(quest.answer.clone()) + }; + let path = config.full_quests_path(); + match quest.save(path) { + Ok(_) => println!("Updated quest #{}", quest.id), + Err(error) => eprintln!("Error while updating quest: {error}") + } + }, + QuestCommands::Delete(args) => { + let mut path = config.full_quests_path(); + path.push(format!("{}.toml", args.id)); + match Quest::delete(path) { + Ok(_) => println!("Successfully deleted quest #{}", args.id), + Err(error) => eprintln!("Error deleting quest #{}: {}", args.id, error), + } + }, + } + } + } } diff --git a/src/quest/mod.rs b/src/quest/mod.rs index e3a0d1b..6c95f69 100644 --- a/src/quest/mod.rs +++ b/src/quest/mod.rs @@ -8,7 +8,7 @@ use serde::{ Serialize, Deserialize }; use error::QuestError; /// Difficulty of the quest -#[derive(Serialize, Deserialize, Debug, PartialEq)] +#[derive(Serialize, Deserialize, Debug, PartialEq, Clone, Copy)] pub enum QuestDifficulty { /// Easy quest Easy,