summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Sotoudeh <matthewsot@outlook.com>2022-01-23 22:23:17 -0800
committerMatthew Sotoudeh <matthewsot@outlook.com>2022-01-23 22:23:17 -0800
commit0c64e06848292cf473b7d642cc02922ef9dcc2f4 (patch)
treeee3003f3ad97006e82c70e32d5d32454a6bbfa25
parent99286549bb6bd205a342bd98fc03223ec263ca45 (diff)
'wtd validate' command working
-rw-r--r--src/dates.rs89
-rw-r--r--src/main.rs26
-rw-r--r--src/task.rs7
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<WTDPa
return paths;
}
+/* This is a pretty rough way of doing it, but it should work. Basically:
+ * - Pull the tasks from wtd.md, record a set of the weeks involved.
+ * - Also pull all tasks from any (future) [week].md files, _removing_ those weeks from the set.
+ * - For every remaining week mentioned in wtd.md but not a [week].md, add a copy of weekly.md for
+ * that week.
+ * - Finally, if there were no future [week].mds, add a copy of weekly.md for a date far in the
+ * future (i.e., not to conflict with any other dates).
+ */
+pub fn relevant_files_starting<'a>(start: &'a NaiveDate) -> Vec<WTDPath> {
+ let start_week = week_start_of(start);
+ let mut paths: Vec<WTDPath> = 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<String> {
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<NaiveDate> {
}
}
+pub fn maybe_valid_week_file(week_file_name: &str) -> Option<NaiveDate> {
+ 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<String> {
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<Task> = 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,
+ }
+}
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback