use clap::Parser; use serde::{Deserialize, Serialize}; use std::io::{BufRead, Write}; use xdg::BaseDirectories; mod cli; fn main() { let args = cli::Args::parse(); let xdg_dirs = BaseDirectories::with_prefix(env!("CARGO_PKG_NAME")).unwrap(); let tasks_file_path = xdg_dirs.place_data_file("data.json").unwrap(); let mut tasks: Vec = std::fs::File::open(&tasks_file_path) .map(|file| serde_json::from_reader(file).unwrap()) .unwrap_or_default(); match args.command { cli::SubCommand::Add { link, name } => { tasks.push(Task { name, link, description: None, }); let mut file = std::fs::File::create(&tasks_file_path).unwrap(); file.write_all(&serde_json::to_vec(&tasks).unwrap()) .unwrap(); println!("added"); } cli::SubCommand::Edit { idx, name, link, no_link, } => { if idx == 0 || idx > tasks.len() { println!("invalid index"); } let mut task = &mut tasks[idx - 1]; if let Some(name) = name { task.name = name; } if let Some(link) = link { task.link = Some(link); } else if no_link { task.link = None; } let mut file = std::fs::File::create(&tasks_file_path).unwrap(); file.write_all(&serde_json::to_vec(&tasks).unwrap()) .unwrap(); println!("changed"); } cli::SubCommand::Remove { idx } => { if idx == 0 || idx > tasks.len() { println!("invalid index"); } println!("You are deleting task:"); println!(" {}", tasks[idx - 1].name); println!(); println!("In most cases you need to `finish` command"); loop { print!("Do you still want to delete the task? (y/N): "); std::io::stdout().flush().unwrap(); let mut stdin = std::io::stdin().lock(); let mut buf = String::new(); stdin.read_line(&mut buf).unwrap(); match buf.chars().next().unwrap_or_default() { '\r' | '\n' | 'n' | 'N' => return, 'y' | 'Y' => break, _ => println!("Unrecognised answer. Please try again."), } } tasks.remove(idx - 1); let mut file = std::fs::File::create(&tasks_file_path).unwrap(); file.write_all(&serde_json::to_vec(&tasks).unwrap()) .unwrap(); println!("removed"); } cli::SubCommand::List => { for (i, task) in tasks.iter().enumerate() { print!("{}. ", i + 1); if task.link.is_some() { print!("(link) "); } println!("{}", task.name); } } cli::SubCommand::Start => { println!("starting..."); println!("-- on start hook found"); println!("-- running..."); println!("> curl ..."); println!("-- status was changed to \"In progress\" successfuly"); println!("started"); } cli::SubCommand::Pause => { println!("pausing..."); println!("paused"); } cli::SubCommand::Finish => { println!("finishing..."); println!("-- on finish hook found"); println!("-- running..."); println!("> curl ..."); println!("-- status was changed to \"Deploy\" successfuly"); println!("finished"); } cli::SubCommand::Status => { println!("Information about your current task:"); println!("[work]"); println!("https://redmine.example.com/issues/4051"); println!( "#4051 Plannig/Assignment: Assign week and day general delvirebles after regular" ); println!("-------------------------------------------------------------------------"); println!("lorem impsum dolor dolor impsum lorem lorem impsum"); println!("lorem dolor impsum lorem lorem impsum"); println!("lorem dolor impsum lorem lorem impsum lorem impsum dolor dolor impsum lorem"); println!("lorem impsum"); } } } #[derive(Deserialize, Serialize)] struct Task { name: String, link: Option, description: Option, // created_at }