feat: CLI quest CRUD
- Quest creation - Quest list retrieving - Quest update - Quest deletion
This commit is contained in:
parent
2e14614bdf
commit
d61011f5ea
2 changed files with 124 additions and 9 deletions
131
src/bin/cli.rs
131
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<QuestDifficulty> 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<QuestDifficulty>,
|
||||
/// Reward for the quest
|
||||
reward: u32,
|
||||
#[arg(long)]
|
||||
reward: Option<u32>,
|
||||
/// Name of the quest
|
||||
name: String,
|
||||
#[arg(long)]
|
||||
name: Option<String>,
|
||||
/// Visible description of the quest
|
||||
description: String,
|
||||
#[arg(long)]
|
||||
description: Option<String>,
|
||||
/// Answer for the quest for admins
|
||||
answer: String
|
||||
#[arg(long)]
|
||||
answer: Option<String>
|
||||
}
|
||||
|
||||
#[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),
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue