1use crate::{CommaSeparated, SpaceSeparated};
2
3#[derive(Debug, PartialEq)]
5pub struct CommandSpec {
6 pub name: &'static str,
8
9 pub description: &'static str,
11
12 pub options: Vec<CommandOption>,
14
15 pub subcommands: Vec<CommandSpec>,
17}
18
19#[derive(Debug, PartialEq)]
21pub struct CommandOption {
22 pub name: &'static str,
24
25 pub position: usize,
27
28 pub description: &'static str,
30
31 pub value: CommandOptionValueKind,
33}
34
35#[derive(Clone, Debug, PartialEq)]
37pub enum CommandOptionValueKind {
38 Optional(Box<CommandOptionValueKind>),
40
41 Multiple(Box<CommandOptionValueKind>),
43
44 String,
46
47 Integer,
49
50 Double,
52}
53
54impl CommandOptionValueKind {
55 pub fn is_optional(&self) -> bool {
57 matches!(self, CommandOptionValueKind::Optional(_))
58 }
59
60 pub fn as_primitive(&self) -> CommandOptionValueKind {
62 match self {
63 CommandOptionValueKind::Optional(t) | CommandOptionValueKind::Multiple(t) => {
64 t.as_primitive()
65 }
66 _ => self.clone(),
67 }
68 }
69}
70
71pub trait CommandOptionValueTy: Sized {
73 fn spec_kind() -> CommandOptionValueKind;
75
76 fn default() -> Option<Self> {
78 None
79 }
80}
81
82impl<T: CommandOptionValueTy> CommandOptionValueTy for Option<T> {
83 fn spec_kind() -> CommandOptionValueKind {
84 CommandOptionValueKind::Optional(Box::new(T::spec_kind()))
85 }
86
87 fn default() -> Option<Self> {
88 Some(None)
89 }
90}
91
92impl CommandOptionValueTy for String {
93 fn spec_kind() -> CommandOptionValueKind {
94 CommandOptionValueKind::String
95 }
96}
97
98impl CommandOptionValueTy for i64 {
99 fn spec_kind() -> CommandOptionValueKind {
100 CommandOptionValueKind::Integer
101 }
102}
103
104impl CommandOptionValueTy for f64 {
105 fn spec_kind() -> CommandOptionValueKind {
106 CommandOptionValueKind::Double
107 }
108}
109
110impl<T: CommandOptionValueTy> CommandOptionValueTy for SpaceSeparated<T> {
111 fn spec_kind() -> CommandOptionValueKind {
112 CommandOptionValueKind::Multiple(Box::new(T::spec_kind()))
113 }
114}
115
116impl<T: CommandOptionValueTy> CommandOptionValueTy for CommaSeparated<T> {
117 fn spec_kind() -> CommandOptionValueKind {
118 CommandOptionValueKind::Multiple(Box::new(T::spec_kind()))
119 }
120}