use crate::condition::{ConditionFind, Direction, Edge}; use chrono::{NaiveDate, NaiveDateTime}; use karlcommon::{Schedule, Task}; use std::{collections::HashMap, ops::Range}; pub struct DiscreteCache { tasks: HashMap, } pub struct DiscreteCacheTask { inner: Task, cached: Option>, cache: Vec>, } impl DiscreteCache { pub fn new_for(tasks: HashMap) -> Self { Self { tasks: HashMap::from_iter( tasks .into_iter() .map(|(k, v)| (k, DiscreteCacheTask::new(v))), ), } } } impl DiscreteCacheTask { pub fn new(inner: Task) -> Self { Self { inner, cached: None, cache: vec![], } } pub fn find(&mut self, from: NaiveDateTime, dir: Direction) -> Range> { assert_eq!(dir, Direction::Forward); // TODO cache // if let Some(c) = self.cached {} match &self.inner.schedule { Schedule::Condition(o) => { let start = o.find(Edge::Start, dir, from); let end = o.find(Edge::End, dir, from); match (start, end) { (Some(start), Some(end)) => { if end < start { if let Some(start) = o.find(Edge::Start, dir.invert(), from) { assert!(start < end); Some(start)..Some(end) } else { None..Some(end) } } else { Some(start)..Some(end) } } (None, Some(end)) => { if let Some(start) = o.find(Edge::Start, dir.invert(), from) { assert!(start < end); Some(start)..Some(end) } else { None..Some(end) } } (Some(start), None) => Some(start)..None, (None, None) => None..None, } } Schedule::Never => None..None, Schedule::Static(_) => None..None, // TODO Schedule::Dynamic { .. } => None..None, // TODO } } } pub trait Overlaps { fn overlaps(&self, v: T) -> bool; } impl Overlaps for Range { fn overlaps(&self, v: i64) -> bool { self.start <= v && v < self.end } } impl Overlaps for Range> { fn overlaps(&self, v: i64) -> bool { match (self.start, self.end) { (Some(s), Some(e)) => s <= v && v < e, (Some(s), None) => s <= v, (None, Some(e)) => v < e, (None, None) => false, } } } impl Overlaps> for Range> { fn overlaps(&self, v: Range) -> bool { self.overlaps(v.start) || self.overlaps(v.end) } }