1use crate::models::TodoList;
8use clap::{Parser, Subcommand};
9use sqlx::SqlitePool;
10use std::path::PathBuf;
11
12#[derive(Parser)]
13#[command(author, version, about, long_about = None)]
14pub struct Cli {
15 #[arg(short, long, default_value = None)]
18 pub data_dir: Option<String>,
19
20 #[command(subcommand)]
21 pub command: Commands,
22}
23
24#[derive(Subcommand)]
25pub enum Commands {
26 Add { content: String },
30
31 Finish { content: String },
35
36 Edit {
40 find: String,
42 replace: String,
44 },
45
46 Clean,
50
51 List,
55
56 Tui,
60
61 Path,
65}
66
67pub async fn execute_command(
68 cli: Cli,
69 mut tdlist: TodoList,
70 pool: &SqlitePool,
71 data_dir: &PathBuf,
72) -> color_eyre::Result<TodoList> {
73 match cli.command {
74 Commands::Add { content } => {
75 tdlist.add_todo_db(content, pool).await?;
76 }
77 Commands::Finish { content } => {
78 tdlist.finish_todo_db(content, pool).await?;
79 }
80 Commands::Edit { find, replace } => {
81 tdlist.edit_todo_db(find, replace, pool).await?;
82 }
83 Commands::Clean => {
84 tdlist.clean_todo_db(pool).await?;
85 }
86 Commands::List => {
87 tdlist.list_todos();
88 }
89 Commands::Tui => {
90 tdlist = crate::tui::app::run_tui(tdlist)?;
91 }
92 Commands::Path => {
93 let db_path = data_dir.join("todos.db");
94 let toml_path = data_dir.join("todos.toml");
95 println!("Data directory: {}", data_dir.display());
96 println!("Database: {}", db_path.display());
97 println!("TOML export: {}", toml_path.display());
98 }
99 }
100
101 tdlist.sync_to_db(pool).await?;
102 Ok(tdlist)
103}
104
105#[cfg(test)]
106mod args_test {
107 use super::*;
108
109 #[test]
110 fn test_add() {
111 let args = vec!["oflow", "add", "Buy milk"];
112 let cli = Cli::try_parse_from(args).expect("Failed to parse arguments");
113
114 match cli.command {
115 Commands::Add { content } => {
116 assert_eq!(content, "Buy milk");
117 }
118 _ => panic!("Expected Add command"),
119 }
120 }
121
122 #[test]
123 fn test_finish() {
124 let args = vec!["oflow", "finish", "Buy milk"];
125 let cli = Cli::try_parse_from(args).expect("Failed to parse arguments");
126
127 match cli.command {
128 Commands::Finish { content } => {
129 assert_eq!(content, "Buy milk");
130 }
131 _ => panic!("Expect Finish command"),
132 }
133 }
134
135 #[test]
136 fn test_edit() {
137 let args = vec!["oflow", "edit", "Buy milk", "Buy eggs"];
138 let cli = Cli::try_parse_from(args).expect("Failed to parse arguments");
139
140 match cli.command {
141 Commands::Edit { find, replace } => {
142 assert_eq!(find, "Buy milk");
143 assert_eq!(replace, "Buy eggs");
144 }
145 _ => panic!("Expect Edit command"),
146 }
147 }
148}