use chrono::naive::NaiveDate; use regex::Regex; use std::convert::TryFrom; use std::fs::DirEntry; use std::str::FromStr; #[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()) } }