Skip to content

Commit

Permalink
feat: Display birthdays in a pretty table
Browse files Browse the repository at this point in the history
  • Loading branch information
ducdetronquito committed Jan 1, 2024
1 parent cb17018 commit 084aef1
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 21 deletions.
19 changes: 19 additions & 0 deletions src/birthday.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ impl Birthday {
birthday_next_year
}
}

pub fn is_today(&self, today: NaiveDate) -> bool {
self.date.month() == today.month() && self.date.day() == today.day()
}
}

#[cfg(test)]
Expand Down Expand Up @@ -68,4 +72,19 @@ mod tests {
NaiveDate::from_ymd_opt(2025, 5, 3).unwrap()
)
}

#[test]
fn test_is_today() {
let birthday = Birthday {
id: 1,
name: "Ben Dover".to_string(),
date: NaiveDate::from_ymd_opt(1990, 5, 3).unwrap(),
};

assert!(birthday.is_today(NaiveDate::from_ymd_opt(2024, 5, 3).unwrap()));

assert!(!birthday.is_today(NaiveDate::from_ymd_opt(2024, 5, 4).unwrap()));

assert!(!birthday.is_today(NaiveDate::from_ymd_opt(2024, 6, 3).unwrap()));
}
}
27 changes: 6 additions & 21 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
mod output;
use anyhow::Result;
use birthday::Birthday;
use chrono::{Datelike, Utc};
use clap::{Parser, Subcommand};

Expand Down Expand Up @@ -38,19 +38,18 @@ enum Command {

fn main() -> Result<()> {
let cli = Cli::parse();
println!("You ran cli with: {:?}", cli);
let today = Utc::now().date_naive();
match cli.command {
Command::Add { name, date } => birthday::add(name, date),
Command::All {} => {
let birthdays = birthday::get_all()?;
print_birthdays(birthdays);
output::output(birthdays, today);
Ok(())
}
Command::Next {} => {
let today = Utc::now().date_naive();
let maybe_birthday = birthday::get_next(today)?;
if let Some(birthday) = maybe_birthday {
print_birthdays(vec![birthday]);
output::output(vec![birthday], today);
}
Ok(())
}
Expand All @@ -61,7 +60,7 @@ fn main() -> Result<()> {
day,
} => {
let birthdays = birthday::search(name, year, month, day)?;
print_birthdays(birthdays);
output::output(birthdays, today);
Ok(())
}
Command::Today {} => {
Expand All @@ -72,22 +71,8 @@ fn main() -> Result<()> {
Some(today.month()),
Some(today.day()),
)?;
print_birthdays(birthdays);
output::output(birthdays, today);
Ok(())
}
}
}

fn print_birthdays(birthdays: Vec<Birthday>) {
let today = Utc::now().date_naive();
for birthday in birthdays {
let age = match birthday.age(today) {
Some(age) => age.to_string(),
None => "".to_owned(),
};
println!(
"Name={} Birthdate={} Age={}",
birthday.name, birthday.date, age
);
}
}
51 changes: 51 additions & 0 deletions src/output.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
use birthday::Birthday;
use chrono::{Datelike, NaiveDate};
use tabled::{settings::Style, Table, Tabled};

#[derive(Tabled)]
struct DisplayedBirthday {
#[tabled(rename = "Id")]
id: i32,
#[tabled(rename = "Name")]
name: String,
#[tabled(rename = "Birthday")]
birthday: String,
#[tabled(rename = "Age")]
age: String,
#[tabled(rename = "Next birthday")]
next_birthday: String,
}

impl DisplayedBirthday {
fn from_birthday(birthday: &Birthday, today: NaiveDate) -> DisplayedBirthday {
let age = birthday.age(today).unwrap();
let birthyear = birthday.date.year();
let next_birthday_in_days = (birthday.next(today) - today).num_days();
let next_birthday = if birthday.is_today(today) {
"today".to_string()
} else {
match next_birthday_in_days {
1 => "1 day".to_string(),
_ => format!("{next_birthday_in_days} days"),
}
};
DisplayedBirthday {
id: birthday.id,
name: birthday.name.clone(),
birthday: birthday.date.format("%d %B").to_string(),
age: format!("{age} ({birthyear})"),
next_birthday,
}
}
}

pub fn output(birthdays: Vec<Birthday>, today: NaiveDate) {
let displayed_birthdays: Vec<DisplayedBirthday> = birthdays
.iter()
.map(|birthday| DisplayedBirthday::from_birthday(birthday, today))
.collect();
let table = Table::new(displayed_birthdays)
.with(Style::rounded())
.to_string();
println!("{table}")
}

0 comments on commit 084aef1

Please sign in to comment.