From 0c64e06848292cf473b7d642cc02922ef9dcc2f4 Mon Sep 17 00:00:00 2001 From: Matthew Sotoudeh Date: Sun, 23 Jan 2022 22:23:17 -0800 Subject: 'wtd validate' command working --- src/dates.rs | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- src/main.rs | 26 +++++++++++++++++- src/task.rs | 7 +++++ 3 files changed, 120 insertions(+), 2 deletions(-) diff --git a/src/dates.rs b/src/dates.rs index 09aac82..069af3f 100644 --- a/src/dates.rs +++ b/src/dates.rs @@ -1,5 +1,7 @@ +use std::fs; use std::path::Path; -// use std::str::FromStr; +use std::collections::HashSet; +use crate::tasks_from_path; // use chrono::{Datelike, NaiveDate, NaiveTime, Weekday, Duration, Timelike}; use chrono::{Datelike, NaiveDate, Duration}; @@ -47,6 +49,79 @@ pub fn relevant_files<'a>(start: &'a NaiveDate, end: &'a NaiveDate) -> Vec(start: &'a NaiveDate) -> Vec { + let start_week = week_start_of(start); + let mut paths: Vec = vec![]; + let mut weeks = HashSet::new(); + let mut oldest_date: NaiveDate = *start; + if let Some(path) = path_if_exists("wtd.md") { + paths.push(WTDPath { + path: path, + week_start: None, + is_weekly_file: false, + }); + for task in tasks_from_path(paths.last().unwrap()) { + if task.date < *start { + continue; + } + if task.date > oldest_date { + oldest_date = task.date; + } + let week = week_start_of(&task.date); + weeks.insert(week); + } + } + + // https://stackoverflow.com/questions/26076005 + for path in fs::read_dir("./").unwrap() { + let mut file_name = path.unwrap().path().to_str().unwrap().to_string(); + file_name.remove(0); + file_name.remove(0); // removes the ./ + if let Some(week) = maybe_valid_week_file(&file_name) { + if week < start_week { + continue; + } + if week + Duration::days(6) > oldest_date { + oldest_date = week + Duration::days(6); + } + paths.push(WTDPath { + path: path_if_exists(&file_name).unwrap(), + week_start: Some(week), + is_weekly_file: false, + }); + weeks.remove(&week); + } + } + + let weekly = path_if_exists("weekly.md"); + if weekly.is_some() { + for week in &weeks { + paths.push(WTDPath { + path: weekly.as_ref().unwrap().to_string(), + week_start: Some(*week), + is_weekly_file: true, + }); + } + if weeks.len() == 0 { + paths.push(WTDPath { + path: weekly.as_ref().unwrap().to_string(), + week_start: Some(week_start_of(&(oldest_date + Duration::days(7)))), + is_weekly_file: true, + }); + } + } + + return paths; +} + fn week_file(week_start: NaiveDate) -> Option { let filename = week_start.format("%b_%d_%Y.md").to_string().to_lowercase(); return path_if_exists(&filename); @@ -62,6 +137,18 @@ pub fn parse_week_str(week_str: &str) -> Option { } } +pub fn maybe_valid_week_file(week_file_name: &str) -> Option { + match week_file_name.rsplit_once(".") { + Some((name, "md")) => { + if let Some(date) = parse_week_str(name) { + return if week_start_of(&date) == date { Some(date) } else { None }; + } + return None; + }, + _ => return None, + } +} + fn path_if_exists(name: &str) -> Option { return if Path::new(name).exists() { Some(name.to_string()) } else { None }; } diff --git a/src/main.rs b/src/main.rs index 59a7a0d..06431e8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -54,7 +54,31 @@ fn command_generate(week: &str) { } fn command_validate() { - // TODO + let today = Local::now().date().naive_local(); + let paths = relevant_files_starting(&today); + let mut tasks: Vec = vec![]; + for path in paths { + for task in tasks_from_path(&path) { + if task.date >= today && task.start_time.is_some() && task.end_time.is_some() { + tasks.push(task); + } + } + } + tasks.sort_by(cmp_tasks); + let n_tasks = tasks.len(); + for i in 0..n_tasks { + let task_a = &tasks[i]; + for j in (i + 1)..n_tasks { + let task_b = &tasks[j]; + if tasks_overlap(task_a, task_b) { + println!("Overlap found: '{}' overlaps with '{}'", + task_a.raw.replace("\n", "").trim(), + task_b.raw.replace("\n", "").trim()); + } else { + break; + } + } + } } // https://doc.rust-lang.org/std/fs/struct.File.html diff --git a/src/task.rs b/src/task.rs index 952a35e..817628d 100644 --- a/src/task.rs +++ b/src/task.rs @@ -29,3 +29,10 @@ pub fn does_overlap(timespan_start: &NaiveTime, timespan_end: &NaiveTime, task: _ => false, } } + +pub fn tasks_overlap(task_a: &Task, task_b: &Task) -> bool { + return match [task_a.start_time, task_a.end_time] { + [Some(start), Some(end)] => does_overlap(&start, &end, task_b), + _ => false, + } +} -- cgit v1.2.3