From 3995a47078f39bf8c0592a4f0a92d77884bb701d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Ortega=20Froysa?= Date: Wed, 27 Jul 2022 19:11:03 +0200 Subject: [PATCH] Implement active day functionality. --- Cargo.lock | 20 ++++++++++++++++ Cargo.toml | 3 +-- src/habit.rs | 39 +++++++++++++++++++++++++++++- src/habitmgr.rs | 63 ++++++++++++++++++++++++++++++++++++++++++------- 4 files changed, 113 insertions(+), 12 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 697cba7..1c4c728 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -85,6 +85,7 @@ dependencies = [ "serde", "serde_json", "structopt", + "time", "uuid", ] @@ -106,6 +107,15 @@ version = "0.2.126" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836" +[[package]] +name = "num_threads" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2819ce041d2ee131036f4fc9d6ae7ae125a3a40e97ba64d04fe799ad9dabbb44" +dependencies = [ + "libc", +] + [[package]] name = "ppv-lite86" version = "0.2.16" @@ -271,6 +281,16 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "time" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72c91f41dcb2f096c05f0873d667dceec1087ce5bcf984ec8ffb19acddbb3217" +dependencies = [ + "libc", + "num_threads", +] + [[package]] name = "unicode-ident" version = "1.0.1" diff --git a/Cargo.toml b/Cargo.toml index c38691c..c06aa42 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,10 +7,9 @@ description = "A CLI habit tracker." readme = "./README.md" license = "AGPL-3.0-or-later" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - [dependencies] structopt = "0.3" uuid = { version = "1.1", features = [ "v4", "fast-rng", "macro-diagnostics" ] } serde = { version = "1.0", features = [ "derive" ] } serde_json = "1.0" +time = { version = "0.3", features = [ "local-offset" ] } diff --git a/src/habit.rs b/src/habit.rs index 25c3308..18fbf75 100644 --- a/src/habit.rs +++ b/src/habit.rs @@ -18,6 +18,7 @@ use uuid::Uuid; use serde::{Serialize, Deserialize}; +use time::OffsetDateTime; #[derive(Serialize, Deserialize, Debug)] pub struct Habit @@ -26,11 +27,13 @@ pub struct Habit name:String, bad:bool, weight:u8, + // Day 0 is Monday. Use number_days_from_monday() to determine index. + days_active:[bool;7], } impl Habit { - pub fn new(name:String, bad:bool, weight:u8) -> Self + pub fn new(name:String, bad:bool, weight:u8, days_active:[bool;7]) -> Self { Self { @@ -38,9 +41,42 @@ impl Habit name, bad, weight, + days_active, } } + pub fn active_days_string(&self) -> String + { + let mut res:String = String::new(); + + for (i,v) in self.days_active.iter().enumerate() + { + if *v + { + res.push_str(match i { + 0 => "mon", + 1 => "tue", + 2 => "wed", + 3 => "thu", + 4 => "fri", + 5 => "sat", + 6 => "sun", + _ => "unk", // this one will never occur, but the compiler complains + }); + res.push(','); + } + } + res.pop(); + + return res; + } + + pub fn active_today(&self) -> bool + { + return self.days_active[OffsetDateTime::now_local().unwrap() + .weekday().number_days_from_monday() as usize] + } + pub fn get_uid(&self) -> &String { &self.uid } pub fn get_name(&self) -> &String { &self.name } pub fn get_bad(&self) -> bool { self.bad } @@ -49,4 +85,5 @@ impl Habit pub fn set_name(&mut self, name:String) { self.name = name; } pub fn set_bad(&mut self, bad:bool) { self.bad = bad; } pub fn set_weight(&mut self, weight:u8) { self.weight = weight; } + pub fn set_days(&mut self, days:[bool;7]) { self.days_active = days; } } diff --git a/src/habitmgr.rs b/src/habitmgr.rs index cf628ae..221e0ae 100644 --- a/src/habitmgr.rs +++ b/src/habitmgr.rs @@ -19,6 +19,7 @@ use std::path::PathBuf; use std::fs::OpenOptions; use std::io::{BufReader, BufWriter}; +use time::Weekday; use crate::habit::Habit; @@ -95,9 +96,40 @@ impl HabitMgr }); } - pub fn add(&mut self, name:String, bad:bool, weight:u8, _days:String) + fn days_array_from_string(days:String) -> [bool;7] { - self.habits.push(Habit::new(name.clone(), bad, weight)); + let days_list = days.split(","); + let mut days_active:[bool;7] = [ false; 7 ]; + for i in days_list + { + match i + { + "mon" => + days_active[Weekday::Monday.number_days_from_monday() as usize] = true, + "tue" => + days_active[Weekday::Tuesday.number_days_from_monday() as usize] = true, + "wed" => + days_active[Weekday::Wednesday.number_days_from_monday() as usize] = true, + "thu" => + days_active[Weekday::Thursday.number_days_from_monday() as usize] = true, + "fri" => + days_active[Weekday::Friday.number_days_from_monday() as usize] = true, + "sat" => + days_active[Weekday::Saturday.number_days_from_monday() as usize] = true, + "sun" => + days_active[Weekday::Sunday.number_days_from_monday() as usize] = true, + _ => + panic!("Day {} not recognized!", i), + } + } + + return days_active; + } + + pub fn add(&mut self, name:String, bad:bool, weight:u8, days:String) + { + let days_active = HabitMgr::days_array_from_string(days); + self.habits.push(Habit::new(name.clone(), bad, weight, days_active)); self.export_habits(); println!("New habit {} added.", &name); @@ -116,6 +148,7 @@ impl HabitMgr println!("Name: {}", habit.get_name()); println!("ID: {}", id); println!("UID: {}", habit.get_uid()); + println!("Active Days: {}", habit.active_days_string()); println!("Bad: {}", habit.get_bad()); println!("Weight: {}", habit.get_weight()); } @@ -124,7 +157,7 @@ impl HabitMgr name:Option, toggle_bad:bool, weight:Option, - _days:Option) + days:Option) { if name.is_some() { @@ -139,26 +172,38 @@ impl HabitMgr { self.habits[id].set_weight(weight.unwrap()); } + if days.is_some() + { + let days_active = HabitMgr::days_array_from_string(days.unwrap()); + self.habits[id].set_days(days_active); + } self.export_habits(); } - pub fn list(&self, _all:bool) + pub fn list(&self, all:bool) { if self.habits.is_empty() { println!("There are no habits. Add one!"); } + else if !all && self.habits.iter().all(|i| !i.active_today()) + { + println!("No active habits available today!"); + } else { println!(" {0: <3} | {1: <5} | {2: <6} | {3}", "id", "bad", "weight", "name"); for (i, habit) in self.habits.iter().enumerate() { - println!(" {0: <3} | {1: <5} | {2: <6} | {3}", - i, - habit.get_bad(), - habit.get_weight(), - habit.get_name()); + if all || habit.active_today() + { + println!(" {0: <3} | {1: <5} | {2: <6} | {3}", + i, + habit.get_bad(), + habit.get_weight(), + habit.get_name()); + } } } }