mod args; mod mgmt; use args::{Args, Config}; use chrono::Datelike; use clap::Parser; use diaryrs::{macros::UnwrapOrFatalAble, time::Time, util}; use indoc::formatdoc; use mgmt::Inventory; use std::fs; use std::io::prelude::*; fn main() { let args = Args::parse(); match args.cmd { args::Commands::Info => { let time = Time::build().unwrap_or_fatal("Failed to determine time information"); let config = Config::read().unwrap_or_fatal("Failed to read config file"); println!("diaryrs"); println!( "[TIME] Timestamp: {}, Timezone: {}", time.timestamp, time.timezone ); println!("[CONFIG] Found at path: {}", config.config_path.display()); println!("[CONFIG] Configuration: {:?}", config) } args::Commands::Today => { let time = Time::build().unwrap_or_fatal("Failed to determine time information"); let config = Config::read().unwrap_or_fatal("Failed to read config file"); let entry = fmt_entry(&time); // Create folder for day (YYYY-MM-DD) let year = time.datetime.format("%Y").to_string(); let month = time.datetime.format("%m").to_string(); let month_name = time.datetime.format("%B").to_string(); let day = time.datetime.format("%d").to_string(); let day_ordinal = util::ordinal(time.datetime.day()); let ymd = format!("{}-{}-{}", year, month, day); let dir_path = config .base_path .join(&year) .join(&month_name) .join(&day_ordinal); fs::create_dir_all(&dir_path) .unwrap_or_fatal("Failed to create directory for today's entry"); // Write entry to file if not exists let file_path = dir_path.join(format!("{ymd}.md")); let mut file_handle = fs::OpenOptions::new() .write(true) .create_new(true) .open(file_path) .unwrap_or_fatal("Error opening today's entry for writing!"); match file_handle.write(entry.as_bytes()) { Ok(_) => println!("Successfully wrote diary entry for {ymd}. Happy journaling!"), Err(e) => eprintln!("Error: Failed to write diary entry: {e}"), }; } args::Commands::Inventory => { let config = Config::read().unwrap_or_fatal("Failed to read config file"); let time = Time::build().unwrap_or_fatal("Failed to determine time information"); let year = time.datetime.format("%Y").to_string(); let month_name = time.datetime.format("%B").to_string(); let day_ordinal = util::ordinal(time.datetime.day()); let inventory = Inventory::take(&config).unwrap_or_fatal("Failed to take inventory"); println!("*** Inventory ***"); println!( "For the {day_ordinal} of {month_name}, {year} in {}", time.timezone ); println!(); println!("You have {} diary entries so far.", inventory.entries); println!( "You have written {} words so far, with an average of {} words per entry.", inventory.word_count, inventory.avg_word_count ); println!(); println!("*** Happy journaling! ***") } } } fn fmt_entry(time: &Time) -> String { let yaml = formatdoc!( r#" --- timestamp: "{}" timezone: "{}" ---"#, time.timestamp, time.timezone ); formatdoc!( " {} # Dreams # Entry Dear Diary, ", yaml ) }