/* * Copyright (C) 2022 Ortega Froysa, Nicolás * Author: Ortega Froysa, Nicolás * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ use structopt::StructOpt; use structopt::clap::AppSettings; use std::env; use std::path::PathBuf; use std::fs; mod habit; mod habitmgr; use habitmgr::HabitMgr; #[derive(StructOpt)] #[structopt( setting = AppSettings::InferSubcommands, about = "A CLI tool to help form good habits and lose bad ones.")] struct Opts { #[structopt(subcommand)] cmd:Option, } #[derive(StructOpt)] enum Command { #[structopt(alias = "a")] Add { #[structopt(help = "Name of the new habit")] name:String, #[structopt(long, short, help = "Days the new habit is active", default_value = "mon,tue,wed,thu,fri,sat,sun")] days:String, #[structopt(long, help = "Assign habit as a bad habit (negative points)")] bad:bool, #[structopt(short, long, help = "Priority of the new habit (L, M, or H)", default_value = "M")] priority:char, }, Commit { }, #[structopt(alias = "del")] Delete { #[structopt(help = "ID of the habit to delete")] id:usize, }, #[structopt(alias = "i")] Info { #[structopt(help = "ID of the habit to show information for")] id:usize, }, #[structopt(alias = "ls")] List { #[structopt(short, long, help = "List all active habits")] all:bool, }, #[structopt(alias = "mod")] Modify { #[structopt(help = "ID of the habit to modify")] id:usize, #[structopt(short, long, help = "New name for the habit")] name:Option, #[structopt(short, long, help = "New priority for the habit (L, M, or H)")] priority:Option, #[structopt(long, short, help = "New days the habit is active")] days:Option, #[structopt(long, help = "Toggle the 'bad' value of the habit")] toggle_bad:bool, }, Stats { }, #[structopt(alias = "vac")] Vacation { }, } fn main() { let opts = Opts::from_args(); let data_dir = PathBuf::from( env::var("XDG_DATA_HOME") .unwrap_or_else(|e| { panic!("Error: {}", e); })) .join("htracker"); if data_dir.exists() && data_dir.is_file() { panic!("Error: file exists at '{}', please (re)move it.", data_dir.display()); } else if !data_dir.exists() { println!("First run: files will be stored in {}", data_dir.display()); fs::create_dir_all(&data_dir) .unwrap_or_else(|e| { panic!("Filesystem error: {}", e); }); } let mut hmgr = HabitMgr::new(&data_dir); match opts.cmd { None => hmgr.list(false), Some(c) => match c { Command::Add { name, days, bad, priority } => hmgr.add(name, bad, priority, days), Command::Delete { id } => hmgr.delete(id), Command::Info { id } => hmgr.habit_info(id), Command::List { all } => hmgr.list(all), Command::Modify { id, name, priority, days, toggle_bad } => hmgr.modify(id, name, toggle_bad, priority, days), _ => todo!(), }, } }