Implement active day functionality.

This commit is contained in:
Nicolás A. Ortega Froysa 2022-07-27 19:11:03 +02:00
parent d5af968cb9
commit 3995a47078
4 changed files with 113 additions and 12 deletions

20
Cargo.lock generated
View File

@ -85,6 +85,7 @@ dependencies = [
"serde", "serde",
"serde_json", "serde_json",
"structopt", "structopt",
"time",
"uuid", "uuid",
] ]
@ -106,6 +107,15 @@ version = "0.2.126"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836" 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]] [[package]]
name = "ppv-lite86" name = "ppv-lite86"
version = "0.2.16" version = "0.2.16"
@ -271,6 +281,16 @@ dependencies = [
"unicode-width", "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]] [[package]]
name = "unicode-ident" name = "unicode-ident"
version = "1.0.1" version = "1.0.1"

View File

@ -7,10 +7,9 @@ description = "A CLI habit tracker."
readme = "./README.md" readme = "./README.md"
license = "AGPL-3.0-or-later" license = "AGPL-3.0-or-later"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
structopt = "0.3" structopt = "0.3"
uuid = { version = "1.1", features = [ "v4", "fast-rng", "macro-diagnostics" ] } uuid = { version = "1.1", features = [ "v4", "fast-rng", "macro-diagnostics" ] }
serde = { version = "1.0", features = [ "derive" ] } serde = { version = "1.0", features = [ "derive" ] }
serde_json = "1.0" serde_json = "1.0"
time = { version = "0.3", features = [ "local-offset" ] }

View File

@ -18,6 +18,7 @@
use uuid::Uuid; use uuid::Uuid;
use serde::{Serialize, Deserialize}; use serde::{Serialize, Deserialize};
use time::OffsetDateTime;
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]
pub struct Habit pub struct Habit
@ -26,11 +27,13 @@ pub struct Habit
name:String, name:String,
bad:bool, bad:bool,
weight:u8, weight:u8,
// Day 0 is Monday. Use number_days_from_monday() to determine index.
days_active:[bool;7],
} }
impl Habit 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 Self
{ {
@ -38,9 +41,42 @@ impl Habit
name, name,
bad, bad,
weight, 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_uid(&self) -> &String { &self.uid }
pub fn get_name(&self) -> &String { &self.name } pub fn get_name(&self) -> &String { &self.name }
pub fn get_bad(&self) -> bool { self.bad } 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_name(&mut self, name:String) { self.name = name; }
pub fn set_bad(&mut self, bad:bool) { self.bad = bad; } 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_weight(&mut self, weight:u8) { self.weight = weight; }
pub fn set_days(&mut self, days:[bool;7]) { self.days_active = days; }
} }

View File

@ -19,6 +19,7 @@
use std::path::PathBuf; use std::path::PathBuf;
use std::fs::OpenOptions; use std::fs::OpenOptions;
use std::io::{BufReader, BufWriter}; use std::io::{BufReader, BufWriter};
use time::Weekday;
use crate::habit::Habit; 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(); self.export_habits();
println!("New habit {} added.", &name); println!("New habit {} added.", &name);
@ -116,6 +148,7 @@ impl HabitMgr
println!("Name: {}", habit.get_name()); println!("Name: {}", habit.get_name());
println!("ID: {}", id); println!("ID: {}", id);
println!("UID: {}", habit.get_uid()); println!("UID: {}", habit.get_uid());
println!("Active Days: {}", habit.active_days_string());
println!("Bad: {}", habit.get_bad()); println!("Bad: {}", habit.get_bad());
println!("Weight: {}", habit.get_weight()); println!("Weight: {}", habit.get_weight());
} }
@ -124,7 +157,7 @@ impl HabitMgr
name:Option<String>, name:Option<String>,
toggle_bad:bool, toggle_bad:bool,
weight:Option<u8>, weight:Option<u8>,
_days:Option<String>) days:Option<String>)
{ {
if name.is_some() if name.is_some()
{ {
@ -139,20 +172,31 @@ impl HabitMgr
{ {
self.habits[id].set_weight(weight.unwrap()); 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(); self.export_habits();
} }
pub fn list(&self, _all:bool) pub fn list(&self, all:bool)
{ {
if self.habits.is_empty() if self.habits.is_empty()
{ {
println!("There are no habits. Add one!"); 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 else
{ {
println!(" {0: <3} | {1: <5} | {2: <6} | {3}", println!(" {0: <3} | {1: <5} | {2: <6} | {3}",
"id", "bad", "weight", "name"); "id", "bad", "weight", "name");
for (i, habit) in self.habits.iter().enumerate() for (i, habit) in self.habits.iter().enumerate()
{
if all || habit.active_today()
{ {
println!(" {0: <3} | {1: <5} | {2: <6} | {3}", println!(" {0: <3} | {1: <5} | {2: <6} | {3}",
i, i,
@ -163,3 +207,4 @@ impl HabitMgr
} }
} }
} }
}