aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock56
-rw-r--r--Cargo.toml1
-rw-r--r--protocol.d.ts40
-rw-r--r--src/condition.rs156
-rw-r--r--src/lib.rs2
-rw-r--r--src/main.rs3
-rw-r--r--src/occurence.rs25
-rw-r--r--src/protocol.rs2
8 files changed, 237 insertions, 48 deletions
diff --git a/Cargo.lock b/Cargo.lock
index e7a6415..73eb781 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -29,10 +29,17 @@ dependencies = [
]
[[package]]
+name = "autocfg"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
+
+[[package]]
name = "calender-thing"
version = "0.1.0"
dependencies = [
"anyhow",
+ "chrono",
"crossbeam-channel",
"env_logger",
"log",
@@ -47,6 +54,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
+name = "chrono"
+version = "0.4.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73"
+dependencies = [
+ "libc",
+ "num-integer",
+ "num-traits",
+ "time",
+ "winapi",
+]
+
+[[package]]
name = "crossbeam-channel"
version = "0.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -128,6 +148,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
[[package]]
+name = "num-integer"
+version = "0.1.45"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9"
+dependencies = [
+ "autocfg",
+ "num-traits",
+]
+
+[[package]]
+name = "num-traits"
+version = "0.2.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd"
+dependencies = [
+ "autocfg",
+]
+
+[[package]]
name = "proc-macro2"
version = "1.0.39"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -220,12 +259,29 @@ dependencies = [
]
[[package]]
+name = "time"
+version = "0.1.44"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255"
+dependencies = [
+ "libc",
+ "wasi",
+ "winapi",
+]
+
+[[package]]
name = "unicode-ident"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d22af068fba1eb5edcb4aea19d382b2a3deb4c8f9d475c589b6ada9e0fd493ee"
[[package]]
+name = "wasi"
+version = "0.10.0+wasi-snapshot-preview1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
+
+[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/Cargo.toml b/Cargo.toml
index 45bcda5..b3eb94a 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -10,4 +10,5 @@ log = "0.4.17"
env_logger = "0.9.0"
crossbeam-channel = "0.5.4"
serde_json = "1.0.81"
+chrono = "0.4.19"
diff --git a/protocol.d.ts b/protocol.d.ts
index 36bf3e1..0657cdf 100644
--- a/protocol.d.ts
+++ b/protocol.d.ts
@@ -36,32 +36,34 @@ interface Task {
deadline?: Condition,
}
-/*
- { and: [
- { or: [{ dayofweak: 0 }, { dayofweak: 1 }] },
- { weekofmonth: 0 }
- { hour: [11, 13] }
- ]}
+/*
+ 11:00 - 12:00 every first monday of the month
+
+ and: [
+ range: {prop: "hour", min: 11, max: 12},
+ equal: {prop: "dayofweek", value: 0},
+ equal: {prop: "weekofmonth", value: 0},
+ ]
*/
// should only have one property
interface Condition {
from: Condition
- to: Condition
or: Condition[]
and: Condition[]
- year?: [number, number],
- monthofyear?: [number, number],
- weekofmonth?: [number, number],
- dayofyear?: [number, number],
- dayofmonth?: [number, number],
- dayofweek?: [number, number],
-
- hour?: [number, number],
- minute?: [number, number],
- second?: [number, number],
-
- unix?: [number, number],
+ equal?: { prop: Thing, value: number, mod?: number }
+ range?: { prop: Thing, min: number, max: number, mod?: number }
}
+
+type Thing = "year"
+ | "monthofyear"
+ | "weekofmonth"
+ | "dayofyear"
+ | "dayofmonth"
+ | "dayofweek"
+ | "hour"
+ | "minute"
+ | "second"
+ | "unix" \ No newline at end of file
diff --git a/src/condition.rs b/src/condition.rs
new file mode 100644
index 0000000..7a873a8
--- /dev/null
+++ b/src/condition.rs
@@ -0,0 +1,156 @@
+use std::cmp::{max, min};
+
+use chrono::{Datelike, NaiveDate, NaiveDateTime, NaiveTime};
+use serde::{Deserialize, Serialize};
+use Direction::*;
+use Edge::*;
+
+#[derive(Debug, Clone, Serialize, Deserialize)]
+pub enum Condition {
+ From(Box<Condition>),
+
+ Or(Vec<Condition>),
+ And(Vec<Condition>),
+ Invert(Box<Condition>),
+
+ Equal {
+ prop: Property,
+ value: i32,
+ modulus: Option<i32>,
+ },
+ Range {
+ prop: Property,
+ min: i32,
+ max: i32,
+ modulus: Option<i32>,
+ },
+}
+
+#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
+pub enum Property {
+ Year,
+ Monthofyear,
+ Weekofmonth,
+ Dayofyear,
+ Dayofmonth,
+ Dayofweek,
+ Hour,
+ Minute,
+ Second,
+ Unix,
+}
+
+#[derive(Debug, Clone, Serialize, Deserialize)]
+pub struct Range<T>(T, T);
+impl<T: PartialOrd + PartialEq> Range<T> {
+ pub fn includes(&self, a: T) -> bool {
+ a > self.0 && a < self.1
+ }
+}
+
+#[derive(Debug, Clone, Copy)]
+pub enum Edge {
+ Start,
+ End,
+}
+#[derive(Debug, Clone, Copy)]
+pub enum Direction {
+ Forward,
+ Backward,
+}
+
+impl Condition {
+ pub fn find(&self, edge: Edge, dir: Direction, from: NaiveDateTime) -> Option<NaiveDateTime> {
+ match self {
+ Condition::And(_) => todo!(),
+ Condition::Or(cs) => {
+ cs.iter()
+ .filter_map(|c| c.find(edge, dir, from))
+ .reduce(match dir {
+ Forward => min,
+ Backward => max,
+ })
+ }
+ Condition::From(c) => todo!(),
+ Condition::Invert(c) => c.find(edge.invert(), dir, from),
+ Condition::Equal {
+ prop,
+ value,
+ modulus,
+ } => {
+ let geq = match dir {
+ Forward => |a: i32, b: i32| a >= b,
+ Backward => |a: i32, b: i32| a < b,
+ };
+ let off = match edge {
+ Start => 0,
+ End => 1,
+ };
+ match prop {
+ Property::Year => {
+ if geq(from.year(), *value + off) {
+ None
+ } else {
+ Some(NaiveDateTime::new(
+ NaiveDate::from_ymd(*value + off, 1, 1),
+ NaiveTime::from_hms(0, 0, 0),
+ ))
+ }
+ }
+ Property::Monthofyear => todo!(),
+ Property::Weekofmonth => todo!(),
+ Property::Dayofyear => todo!(),
+ Property::Dayofmonth => todo!(),
+ Property::Dayofweek => todo!(),
+ Property::Hour => todo!(),
+ Property::Minute => todo!(),
+ Property::Second => todo!(),
+ Property::Unix => todo!(),
+ }
+ }
+ Condition::Range {
+ prop,
+ min,
+ max,
+ modulus,
+ } => todo!(),
+ }
+ }
+}
+
+impl Edge {
+ pub fn invert(self) -> Self {
+ match self {
+ Edge::Start => Edge::End,
+ Edge::End => Edge::Start,
+ }
+ }
+}
+
+#[cfg(test)]
+mod test {
+ use super::{Condition, Direction, Edge, Property};
+ use chrono::NaiveDateTime;
+ use std::str::FromStr;
+
+ #[test]
+ fn a() {
+ let cond = Condition::Equal {
+ modulus: None,
+ prop: Property::Year,
+ value: 2023,
+ };
+
+ let dt = NaiveDateTime::from_str("2022-06-07T13:37:48").unwrap();
+ assert_eq!(
+ cond.find(Edge::Start, Direction::Forward, dt).unwrap(),
+ NaiveDateTime::from_str("2023-01-01T00:00:00").unwrap(),
+ );
+ assert_eq!(
+ cond.find(Edge::End, Direction::Forward, dt).unwrap(),
+ NaiveDateTime::from_str("2024-01-01T00:00:00").unwrap(),
+ );
+ assert_eq!(cond.find(Edge::End, Direction::Backward, dt), None);
+ assert_eq!(cond.find(Edge::Start, Direction::Backward, dt), None);
+ }
+}
diff --git a/src/lib.rs b/src/lib.rs
index c5d7a22..d9d2e29 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,3 +1,3 @@
pub mod protocol;
-pub mod occurence;
+pub mod condition;
pub mod interface;
diff --git a/src/main.rs b/src/main.rs
index fb975d6..7a36cb1 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,10 +1,9 @@
-use std::time::Duration;
-
use calender_thing::{
interface::network_loop,
protocol::{ClientboundPacket, ServerboundPacket},
};
use crossbeam_channel::{Receiver, Sender};
+use std::time::Duration;
fn main() {
let (s, r) = crossbeam_channel::unbounded();
diff --git a/src/occurence.rs b/src/occurence.rs
deleted file mode 100644
index 104438a..0000000
--- a/src/occurence.rs
+++ /dev/null
@@ -1,25 +0,0 @@
-use serde::{Deserialize, Serialize};
-
-#[derive(Debug, Serialize, Deserialize)]
-pub enum Condition {
- And(Vec<Condition>),
- Or(Vec<Condition>),
- From(Box<Condition>),
- To(Box<Condition>),
-
- Year(Range),
- Monthofyear(Range),
- Weekofmonth(Range),
- Dayofyear(Range),
- Dayofmonth(Range),
- Dayofweek(Range),
-
- Hour(Range),
- Minute(Range),
- Second(Range),
-
- Unix(Range),
-}
-
-#[derive(Debug, Serialize, Deserialize)]
-pub struct Range(u64, u64);
diff --git a/src/protocol.rs b/src/protocol.rs
index a09f879..e7527eb 100644
--- a/src/protocol.rs
+++ b/src/protocol.rs
@@ -1,6 +1,6 @@
use serde::{Deserialize, Serialize};
-use crate::occurence::Condition;
+use crate::condition::Condition;
#[derive(Debug, Serialize, Deserialize)]
#[serde(tag = "type", content = "data", rename_all = "snake_case")]