1use crate::cli::handlers::CommandCtx;
4use crate::cli::Commands;
5use crate::db::Database;
6use crate::utils::Result;
7use clap_complete::Shell;
8
9pub struct CommandHandler {
10 db: Database,
11}
12
13impl CommandHandler {
14 pub fn new() -> Result<Self> {
15 let db = Database::new()?;
16 Ok(Self { db })
17 }
18
19 #[allow(dead_code)]
20 pub fn from_db(db: Database) -> Self {
21 Self { db }
22 }
23
24 #[allow(dead_code)]
27 pub fn get_db(&self) -> &Database {
28 &self.db
29 }
30
31 pub fn handle(&self, command: Commands) -> Result<()> {
32 let ctx = CommandCtx::new(&self.db);
33 match command {
34 Commands::New {
35 name,
36 description,
37 ticket,
38 ticket_url,
39 template,
40 } => super::handlers::handle_new(
41 &ctx,
42 &name,
43 description.as_deref(),
44 ticket.as_deref(),
45 ticket_url.as_deref(),
46 template.as_deref(),
47 ),
48 Commands::List { all } => super::handlers::handle_list(&ctx, all),
49 Commands::Switch { task_ref } => super::handlers::handle_switch(&ctx, &task_ref),
50 Commands::Status { id, json, all } => super::handlers::handle_info(&ctx, id, json, all),
51 Commands::Desc { description, task } => {
52 super::handlers::handle_desc(&ctx, description.as_deref(), task)
53 }
54 Commands::Ticket {
55 ticket_id,
56 url,
57 task,
58 } => super::handlers::handle_ticket(&ctx, &ticket_id, &url, task),
59 Commands::Archive { task_ref, force } => {
60 super::handlers::handle_archive(&ctx, task_ref.as_deref(), force)
61 }
62 Commands::Todo(cmd) => super::handlers::handle_todo(&ctx, cmd),
63 Commands::Link(cmd) => super::handlers::handle_link(&ctx, cmd),
64 Commands::Scrap(cmd) => super::handlers::handle_scrap(&ctx, cmd),
65 Commands::Sync { legacy } => super::handlers::handle_sync(&ctx, legacy),
66 Commands::Migrate(cmd) => super::handlers::handle_migrate(&ctx, cmd),
67 Commands::Repo(cmd) => super::handlers::handle_repo(&ctx, cmd),
68 Commands::Alias(cmd) => super::handlers::handle_alias(&ctx, cmd),
69 Commands::LlmHelp => super::handlers::handle_llm_help(&ctx),
70 Commands::Completion { shell, dynamic } => {
71 super::handlers::handle_completion(&ctx, shell, dynamic)
72 }
73 Commands::Complete { completion_type } => {
74 super::handlers::handle_complete(&ctx, completion_type)
75 }
76 Commands::Config(cmd) => super::handlers::handle_config(&ctx, cmd),
77 Commands::Webui { .. } => unreachable!("Webui command is handled in main.rs"),
78 }
79 }
80
81 #[allow(dead_code)]
82 pub(crate) fn handle_llm_help(&self) -> Result<()> {
83 super::handlers::handle_llm_help(&CommandCtx::new(&self.db))
84 }
85
86 #[allow(dead_code)]
87 pub(crate) fn handle_completion(&self, shell: Shell, dynamic: bool) -> Result<()> {
88 super::handlers::handle_completion(&CommandCtx::new(&self.db), shell, dynamic)
89 }
90}
91
92#[cfg(test)]
93mod tests {
94 use super::*;
95 use crate::db::Database;
96
97 #[test]
98 fn test_llm_help() {
99 let db = Database::new_in_memory().unwrap();
100 let handler = CommandHandler::from_db(db);
101
102 let result = handler.handle_llm_help();
103 assert!(result.is_ok());
104 }
105
106 #[test]
107 fn test_completion() {
108 let db = Database::new_in_memory().unwrap();
109 let handler = CommandHandler::from_db(db);
110
111 for shell in [
112 clap_complete::Shell::Bash,
113 clap_complete::Shell::Zsh,
114 clap_complete::Shell::Fish,
115 clap_complete::Shell::PowerShell,
116 ] {
117 let result = handler.handle_completion(shell, false);
118 assert!(
119 result.is_ok(),
120 "Static completion generation failed for {:?}",
121 shell
122 );
123 }
124
125 for shell in [clap_complete::Shell::Bash, clap_complete::Shell::Zsh] {
126 let result = handler.handle_completion(shell, true);
127 assert!(
128 result.is_ok(),
129 "Dynamic completion generation failed for {:?}",
130 shell
131 );
132 }
133 }
134}