1use rdice_core::error::{DiceError, Result};
2
3#[derive(Debug, Clone, PartialEq, Eq)]
4pub enum Command {
5 ManagerDice,
6 ManagerTrays,
7 Overview,
8 History,
9 OpenTray(String),
10 DiceNew { name: String, faces: Vec<String> },
11 DiceDelete(String),
12 DiceEdit { name: String, faces: Vec<String> },
13 TrayNew(String),
14 TrayDelete(String),
15 TrayRename { old_name: String, new_name: String },
16 Quit,
17}
18
19pub fn parse_command(input: &str) -> Result<Command> {
20 let parts = input.split_whitespace().collect::<Vec<_>>();
21 if parts.is_empty() {
22 return invalid_command(input);
23 }
24
25 match parts.as_slice() {
26 ["manager", "dice"] => Ok(Command::ManagerDice),
27 ["manager", "trays"] => Ok(Command::ManagerTrays),
28 ["overview"] => Ok(Command::Overview),
29 ["history"] => Ok(Command::History),
30 ["tray", name] => Ok(Command::OpenTray((*name).to_string())),
31 ["dice", "new", name, faces @ ..] if !faces.is_empty() => Ok(Command::DiceNew {
32 name: (*name).to_string(),
33 faces: faces.iter().map(|face| (*face).to_string()).collect(),
34 }),
35 ["dice", "delete", name] => Ok(Command::DiceDelete((*name).to_string())),
36 ["dice", "edit", name, faces @ ..] if !faces.is_empty() => Ok(Command::DiceEdit {
37 name: (*name).to_string(),
38 faces: faces.iter().map(|face| (*face).to_string()).collect(),
39 }),
40 ["tray", "new", name] => Ok(Command::TrayNew((*name).to_string())),
41 ["tray", "delete", name] => Ok(Command::TrayDelete((*name).to_string())),
42 ["tray", "rename", old_name, new_name] => Ok(Command::TrayRename {
43 old_name: (*old_name).to_string(),
44 new_name: (*new_name).to_string(),
45 }),
46 ["quit"] | ["q"] => Ok(Command::Quit),
47 _ => invalid_command(input),
48 }
49}
50
51fn invalid_command<T>(input: &str) -> Result<T> {
52 Err(DiceError::InvalidArguments(format!(
53 "invalid command: {input}"
54 )))
55}