1use crate::error::*;
2use crate::Callback;
3use crate::Parameter;
4use std::collections::BTreeMap;
5use std::fmt;
6
7pub struct Command<Context, E> {
9 pub(crate) name: String,
10 pub(crate) aliases: Vec<String>,
11 pub(crate) parameters: Vec<Parameter>,
12 pub(crate) callback: Callback<Context, E>,
13 pub(crate) help_summary: Option<String>,
14}
15
16impl<Context, E> fmt::Debug for Command<Context, E> {
17 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
18 f.debug_struct("Command")
19 .field("name", &self.name)
20 .field("parameters", &self.parameters)
21 .field("help_summary", &self.help_summary)
22 .finish()
23 }
24}
25
26impl<Context, E> std::cmp::PartialEq for Command<Context, E> {
27 fn eq(&self, other: &Command<Context, E>) -> bool {
28 self.name == other.name
29 && self.parameters == other.parameters
30 && self.help_summary == other.help_summary
31 }
32}
33
34impl<Context, E> Command<Context, E> {
35 pub fn new(name: impl ToString, callback: impl Fn(BTreeMap<String, String>, &mut Context) -> std::result::Result<Option<String>, E> + 'static) -> Self {
37 Self {
38 name: name.to_string(),
39 aliases: vec![],
40 parameters: vec![],
41 callback: Box::new(callback),
42 help_summary: None,
43 }
44 }
45
46 pub fn with_parameter(mut self, parameter: Parameter) -> Result<Command<Context, E>> {
49 if parameter.required && self.parameters.iter().any(|param| !param.required) {
50 return Err(Error::IllegalRequiredError(parameter.name));
51 }
52
53 self.parameters.push(parameter);
54
55 Ok(self)
56 }
57
58 pub fn with_help(mut self, help: impl ToString) -> Command<Context, E> {
60 self.help_summary = Some(help.to_string());
61
62 self
63 }
64
65 pub fn with_alias(mut self, help: impl ToString) -> Command<Context, E> {
67 self.aliases.push(help.to_string());
68
69 self
70 }
71}