htracker/src/main.rs

137 lines
3.5 KiB
Rust

/*
* Copyright (C) 2022 Ortega Froysa, Nicolás <nicolas@ortegas.org>
* Author: Ortega Froysa, Nicolás <nicolas@ortegas.org>
*
* 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 <http://www.gnu.org/licenses/>.
*/
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<Command>,
}
#[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<String>,
#[structopt(short, long, help = "New priority for the habit (L, M, or H)")]
priority:Option<char>,
#[structopt(long, short, help = "New days the habit is active")]
days:Option<String>,
#[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!(),
},
}
}