1use crate::cli::SubCmd;
2use crate::config::YamlConfig;
3
4pub trait CommandHandler {
6 fn execute(&self, config: &mut YamlConfig);
7}
8
9macro_rules! command_handlers {
20 (
21 $(
22 $name:ident { $( $field:ident : $ty:ty ),* $(,)? } => |$self_:ident, $cfg:ident| $body:block
23 ),* $(,)?
24 ) => {
25 $(
26 pub struct $name {
27 $( pub $field: $ty, )*
28 }
29
30 impl CommandHandler for $name {
31 fn execute(&$self_, $cfg: &mut YamlConfig) $body
32 }
33 )*
34 };
35}
36
37command_handlers! {
39 SetCmd { alias: String, path: Vec<String> } => |self, config| {
40 crate::command::alias::handle_set(&self.alias, &self.path, config);
41 },
42 RemoveCmd { alias: String } => |self, config| {
43 crate::command::alias::handle_remove(&self.alias, config);
44 },
45 RenameCmd { alias: String, new_alias: String } => |self, config| {
46 crate::command::alias::handle_rename(&self.alias, &self.new_alias, config);
47 },
48 ModifyCmd { alias: String, path: Vec<String> } => |self, config| {
49 crate::command::alias::handle_modify(&self.alias, &self.path, config);
50 },
51
52 NoteCmd { alias: String, category: String } => |self, config| {
54 crate::command::category::handle_note(&self.alias, &self.category, config);
55 },
56 DenoteCmd { alias: String, category: String } => |self, config| {
57 crate::command::category::handle_denote(&self.alias, &self.category, config);
58 },
59
60 ListCmd { part: Option<String> } => |self, config| {
62 crate::command::list::handle_list(self.part.as_deref(), config);
63 },
64 ContainCmd { alias: String, containers: Option<String> } => |self, config| {
65 crate::command::system::handle_contain(&self.alias, self.containers.as_deref(), config);
66 },
67
68 ReportCmd { content: Vec<String> } => |self, config| {
70 crate::command::report::handle_report("report", &self.content, config);
71 },
72 ReportCtlCmd { action: String, arg: Option<String> } => |self, config| {
73 let mut args = vec![self.action.clone()];
74 if let Some(ref a) = self.arg {
75 args.push(a.clone());
76 }
77 crate::command::report::handle_report("reportctl", &args, config);
78 },
79 CheckCmd { line_count: Option<String> } => |self, config| {
80 crate::command::report::handle_check(self.line_count.as_deref(), config);
81 },
82 SearchCmd { line_count: String, target: String, fuzzy: Option<String> } => |self, config| {
83 crate::command::report::handle_search(&self.line_count, &self.target, self.fuzzy.as_deref(), config);
84 },
85
86 TodoCmd { content: Vec<String> } => |self, config| {
88 crate::command::todo::handle_todo(&self.content, config);
89 },
90
91 ChatCmd { content: Vec<String> } => |self, config| {
93 crate::command::chat::handle_chat(&self.content, config);
94 },
95
96 ConcatCmd { name: String, content: Vec<String> } => |self, config| {
98 crate::command::script::handle_concat(&self.name, &self.content, config);
99 },
100
101 TimeCmd { function: String, arg: String } => |self, _config| {
103 crate::command::time::handle_time(&self.function, &self.arg);
104 },
105
106 LogCmd { key: String, value: String } => |self, config| {
108 crate::command::system::handle_log(&self.key, &self.value, config);
109 },
110 ChangeCmd { part: String, field: String, value: String } => |self, config| {
111 crate::command::system::handle_change(&self.part, &self.field, &self.value, config);
112 },
113 ClearCmd {} => |self, _config| {
114 crate::command::system::handle_clear();
115 },
116
117 VersionCmd {} => |self, config| {
119 crate::command::system::handle_version(config);
120 },
121 HelpCmd {} => |self, _config| {
122 crate::command::help::handle_help();
123 },
124 ExitCmd {} => |self, _config| {
125 crate::command::system::handle_exit();
126 },
127 CompletionCmd { shell: Option<String> } => |self, config| {
128 crate::command::system::handle_completion(self.shell.as_deref(), config);
129 },
130
131 VoiceCmd { action: String, copy: bool, model: Option<String> } => |self, config| {
133 crate::command::voice::handle_voice(&self.action, self.copy, self.model.as_deref(), config);
134 },
135}
136
137impl SubCmd {
139 pub fn into_handler(self) -> Box<dyn CommandHandler> {
140 match self {
141 SubCmd::Set { alias, path } => Box::new(SetCmd { alias, path }),
143 SubCmd::Remove { alias } => Box::new(RemoveCmd { alias }),
144 SubCmd::Rename { alias, new_alias } => Box::new(RenameCmd { alias, new_alias }),
145 SubCmd::Modify { alias, path } => Box::new(ModifyCmd { alias, path }),
146
147 SubCmd::Note { alias, category } => Box::new(NoteCmd { alias, category }),
149 SubCmd::Denote { alias, category } => Box::new(DenoteCmd { alias, category }),
150
151 SubCmd::List { part } => Box::new(ListCmd { part }),
153 SubCmd::Contain { alias, containers } => Box::new(ContainCmd { alias, containers }),
154
155 SubCmd::Report { content } => Box::new(ReportCmd { content }),
157 SubCmd::Reportctl { action, arg } => Box::new(ReportCtlCmd { action, arg }),
158 SubCmd::Check { line_count } => Box::new(CheckCmd { line_count }),
159 SubCmd::Search {
160 line_count,
161 target,
162 fuzzy,
163 } => Box::new(SearchCmd {
164 line_count,
165 target,
166 fuzzy,
167 }),
168
169 SubCmd::Todo { content } => Box::new(TodoCmd { content }),
171 SubCmd::Chat { content } => Box::new(ChatCmd { content }),
172
173 SubCmd::Concat { name, content } => Box::new(ConcatCmd { name, content }),
175 SubCmd::Time { function, arg } => Box::new(TimeCmd { function, arg }),
176
177 SubCmd::Log { key, value } => Box::new(LogCmd { key, value }),
179 SubCmd::Change { part, field, value } => Box::new(ChangeCmd { part, field, value }),
180 SubCmd::Clear => Box::new(ClearCmd {}),
181
182 SubCmd::Version => Box::new(VersionCmd {}),
184 SubCmd::Help => Box::new(HelpCmd {}),
185 SubCmd::Exit => Box::new(ExitCmd {}),
186 SubCmd::Completion { shell } => Box::new(CompletionCmd { shell }),
187
188 SubCmd::Voice {
190 action,
191 copy,
192 model,
193 } => Box::new(VoiceCmd {
194 action,
195 copy,
196 model,
197 }),
198 }
199 }
200}