lifec 0.1.1

A CLI tool that displays your life calendar.
Documentation
use chrono::DateTime;
use colored::Colorize;

static WEEKS_PER_YEAR: u32 = 52;

pub enum LifeCalendarStyle {
    Full,
    Short { rows: u32, offset: i32 },
}

pub struct LifeCalendarConfig {
    pub style: LifeCalendarStyle,
    pub years_total: u32,
    pub birth_date: DateTime<chrono::Local>,
}

pub struct LifeCalendar {
    style: LifeCalendarStyle,
    years_total: u32,
    weeks_total: u32,
    weeks_lived: u32,
}

impl LifeCalendar {
    pub fn from_cfg(config: LifeCalendarConfig) -> Self {
        let seconds_lived = chrono::Local::now().timestamp() - config.birth_date.timestamp();
        let weeks_lived = (seconds_lived / 60 / 60 / 24 / 7) as u32;

        Self {
            style: config.style,
            years_total: config.years_total,
            weeks_total: config.years_total * WEEKS_PER_YEAR,
            weeks_lived,
        }
    }

    pub fn print(&self) {
        LifeCalendar::print_delimiter();

        let years_lived = self.weeks_lived / WEEKS_PER_YEAR;

        let (start_year, end_year) = match self.style {
            LifeCalendarStyle::Short { rows, offset } => (
                (years_lived as i32 + offset) as u32,
                (years_lived as i32 + offset) as u32 + rows,
            ),
            LifeCalendarStyle::Full => (0, self.years_total),
        };

        for i in start_year..end_year {
            self.print_row(i);
        }

        LifeCalendar::print_delimiter();

        self.print_stats();
    }

    fn print_delimiter() {
        let delimiter = "".repeat((WEEKS_PER_YEAR + 12) as usize);
        println!("{}", delimiter);
    }

    fn print_row(&self, year: u32) {
        let lived_week_str = "";
        let future_week_str = "";

        let start_week = year * WEEKS_PER_YEAR;
        let end_week = start_week + WEEKS_PER_YEAR;

        // Print age
        print!(" {:2} - {:2} | ", year, year + 1);

        // Print weeks
        for i in start_week..=end_week {
            let week_str = if i <= self.weeks_lived {
                lived_week_str
            } else {
                future_week_str
            };

            print!("{}", week_str);
        }

        print!("\n");
    }

    fn print_stats(&self) {
        let life_progress = (self.weeks_lived as f32) / (self.weeks_total as f32) * 100.0;

        println!("Weeks {}: {}", "lived".green().bold(), self.weeks_lived);
        println!(
            "Weeks {}:  {}",
            "left".blue().bold(),
            self.weeks_total - self.weeks_lived
        );
        println!("Weeks {}: {}\n", "total".bold(), self.weeks_total);

        println!("Your life is {life_progress:.1}% over.");
    }
}