use chrono::naive::NaiveDate; use chrono::{Datelike, Local}; use std::env; use std::fs; use std::path::{Path, PathBuf}; use todo_file::TodoFile; //TODO handle unwraps and errors more uniformly //TODO move TodoFile into its file fn main() { let data_dir = get_data_dir("notes"); println!("{}", data_dir.to_str().unwrap()); let latest_file = get_latest_file(&data_dir).unwrap(); //.expect( // format!( // "Could not find any notes files please use format: {}", // get_file_regex().to_string() // ) // .as_str(), //); println!("Latest file: {:?}", latest_file); let now = Local::now(); let today = NaiveDate::from_ymd_opt(now.year(), now.month(), now.day()); match today { Some(today) if latest_file.date == today => println!("Todays file was created"), Some(today) if latest_file.date < today => println!("Todays file was not created"), Some(today) if latest_file.date > today => println!("Future files were created"), _ => println!("Today never happend!"), } } mod todo_file { use chrono::naive::NaiveDate; use std::convert::TryFrom; use std::fs::DirEntry; use std::str::FromStr; use regex::Regex; #[derive(Debug)] pub struct TodoFile { pub file: DirEntry, pub date: NaiveDate, } impl TodoFile { fn capture_as_number( capture: ®ex::Captures, name: &str, ) -> Result { Ok(capture .name(name) .unwrap() .as_str() .parse::() .ok() .ok_or("Something went wrong".to_owned())?) } pub fn latest_file(a: TodoFile, b: TodoFile) -> TodoFile { if a.date > b.date { a } else { b } } fn get_file_regex() -> Regex { //TODO This would ideally be configurable Regex::new(r"(?P\d{4})-(?P\d{2})-(?P\d{2}).md") .expect("could not create regex") } } impl TryFrom for TodoFile { type Error = String; fn try_from(direntry: DirEntry) -> Result { let re = TodoFile::get_file_regex(); println!("{:?}", re); let file_name = direntry.file_name(); let file_name_str = match file_name.to_str() { Some(name) => name, _ => "", }; println!("{:?}", file_name_str); if let Some(caps) = re.captures(file_name_str) { let year: i32 = Self::capture_as_number(&caps, "year").unwrap(); let month: u32 = Self::capture_as_number(&caps, "month").unwrap(); let day: u32 = Self::capture_as_number(&caps, "day").unwrap(); return Ok(Self { file: direntry, date: NaiveDate::from_ymd_opt(year, month, day).unwrap(), }); }; Err(format!( "Could not parse file name => {{ name: {:?}, re: {:?} }}", file_name, re ) .to_string()) } } } fn get_data_dir(dir_name: &str) -> PathBuf { let mut dir = if let Ok(home) = env::var("HOME") { let mut x = PathBuf::new(); x.push(home); x } else { env::current_dir().expect("PWD environment variable not set") }; dir = dir.join(dir_name); dir } fn get_latest_file(dir: &Path) -> Result { let dir = fs::read_dir(dir).expect(format!("Could not find notes folder: {:?}", dir).as_str()); dir.filter_map(|f| f.ok()) .filter_map(|file| TodoFile::try_from(file).ok()) .reduce(|a, b| TodoFile::latest_file(a, b)) .ok_or("Could not reduce items".to_string()) }