aboutsummaryrefslogtreecommitdiff
path: root/karld/src/helper.rs
diff options
context:
space:
mode:
authormetamuffin <yvchraiqi@protonmail.com>2022-06-11 14:32:45 +0200
committermetamuffin <yvchraiqi@protonmail.com>2022-06-11 14:32:45 +0200
commitc2699d114c921ab2ceb1f467b32a26257dddcf3d (patch)
tree0e886d333d944094c8c66905cac36a21cd010405 /karld/src/helper.rs
parent9769c17c0b4c271c1cfbe726b19a6d3f9250c7c8 (diff)
downloadkarlender-c2699d114c921ab2ceb1f467b32a26257dddcf3d.tar
karlender-c2699d114c921ab2ceb1f467b32a26257dddcf3d.tar.bz2
karlender-c2699d114c921ab2ceb1f467b32a26257dddcf3d.tar.zst
changing the protocol again
Diffstat (limited to 'karld/src/helper.rs')
-rw-r--r--karld/src/helper.rs98
1 files changed, 98 insertions, 0 deletions
diff --git a/karld/src/helper.rs b/karld/src/helper.rs
new file mode 100644
index 0000000..2e601b0
--- /dev/null
+++ b/karld/src/helper.rs
@@ -0,0 +1,98 @@
+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<u64, DiscreteCacheTask>,
+}
+pub struct DiscreteCacheTask {
+ inner: Task,
+ cached: Option<Range<NaiveDateTime>>,
+ cache: Vec<Range<NaiveDateTime>>,
+}
+
+impl DiscreteCache {
+ pub fn new_for(tasks: HashMap<u64, Task>) -> 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<Option<NaiveDateTime>> {
+ 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<T> {
+ fn overlaps(&self, v: T) -> bool;
+}
+impl Overlaps<i64> for Range<i64> {
+ fn overlaps(&self, v: i64) -> bool {
+ self.start <= v && v < self.end
+ }
+}
+impl Overlaps<i64> for Range<Option<i64>> {
+ 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<Range<i64>> for Range<Option<i64>> {
+ fn overlaps(&self, v: Range<i64>) -> bool {
+ self.overlaps(v.start) || self.overlaps(v.end)
+ }
+}