diff options
author | metamuffin <yvchraiqi@protonmail.com> | 2022-06-10 10:47:16 +0200 |
---|---|---|
committer | metamuffin <yvchraiqi@protonmail.com> | 2022-06-10 10:47:16 +0200 |
commit | 3238f8517097745032e19b3e26f57f0465a00b28 (patch) | |
tree | 2c712d2ab45276bed2981dbc32b7a4adeadbc878 /src/condition.rs | |
parent | 829f0dc5ac68ee8a030894ce26c83b1c4eb02104 (diff) | |
download | karlender-3238f8517097745032e19b3e26f57f0465a00b28.tar karlender-3238f8517097745032e19b3e26f57f0465a00b28.tar.bz2 karlender-3238f8517097745032e19b3e26f57f0465a00b28.tar.zst |
move to workspace
Diffstat (limited to 'src/condition.rs')
-rw-r--r-- | src/condition.rs | 365 |
1 files changed, 0 insertions, 365 deletions
diff --git a/src/condition.rs b/src/condition.rs deleted file mode 100644 index bc1b3ec..0000000 --- a/src/condition.rs +++ /dev/null @@ -1,365 +0,0 @@ -use std::cmp::{max, min}; - -use chrono::{Datelike, Duration, NaiveDate, NaiveDateTime, NaiveTime, Timelike}; -use serde::{Deserialize, Serialize}; -use Direction::*; -use Edge::*; - -#[derive(Debug, Clone, Serialize, Deserialize)] -#[serde(rename_all = "snake_case")] -pub enum Condition { - From(Box<Condition>), - - Or(Vec<Condition>), - And(Vec<Condition>), - Invert(Box<Condition>), - - Equal { - prop: Property, - value: i64, - modulus: Option<i64>, - }, - Range { - prop: Property, - min: i64, - max: i64, - modulus: Option<i64>, - }, -} - -#[derive(Debug, Clone, Copy, Serialize, Deserialize)] -#[serde(rename_all = "snake_case")] -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, PartialEq, Eq)] -pub enum Edge { - Start, - End, -} -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub enum Direction { - Forward, - Backward, -} - -impl Condition { - pub fn find( - &self, - edge: Edge, - dir: Direction, - mut from: NaiveDateTime, - ) -> Option<NaiveDateTime> { - match self { - Condition::And(cs) => loop { - // TODO improve efficiency for backward search - let last_start = cs - .iter() - .map(|c| c.find(Start, dir, from)) - .reduce(|a, b| Some(max(a?, b?)))?; - let first_end = cs - .iter() - .map(|c| c.find(End, dir, from)) - .reduce(|a, b| Some(min(a?, b?)))?; - match last_start { - Some(start) => match first_end { - Some(end) => { - if end > start { - break Some(match edge { - Start => start, - End => end, - }); - } else { - from = start - Duration::seconds(10); // TODO proper fix - } - } - None => break Some(start), - }, - None => break None, - } - }, - 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 value = *value; - let off: i64 = match edge { - Start => 0, - End => 1, - }; - let dir_off = match dir { - Forward => 0, - Backward => -1, - }; - match prop { - Property::Year => { - let geq = match dir { - Forward => |a, b| a >= b, - Backward => |a, b| a < b, - }; - - if geq(from.year(), (value + off) as i32) { - None - } else { - Some(NaiveDateTime::new( - NaiveDate::from_ymd((value + off) as i32, 1, 1), - NaiveTime::from_hms(0, 0, 0), - )) - } - } - Property::Monthofyear => { - let rollover = (value + off) / 12; - let value = (value + off) % 12; - // month still coming for this year - if from.month0() < value as u32 { - Some(NaiveDateTime::new( - NaiveDate::from_ymd( - from.year() + (rollover + dir_off) as i32, - value as u32 + 1, - 1, - ), - NaiveTime::from_hms(0, 0, 0), - )) - } else { - Some(NaiveDateTime::new( - NaiveDate::from_ymd( - from.year() + (rollover + dir_off + 1) as i32, - value as u32 + 1, - 1, - ), - NaiveTime::from_hms(0, 0, 0), - )) - } - } - Property::Weekofmonth => todo!(), - Property::Dayofyear => { - todo!() - } - Property::Dayofmonth => { - // let mut target = NaiveDateTime::new( - // NaiveDate::from_ymd(from.year(), from.month(), value as u32), - // NaiveTime::from_hms(0, 0, 0), - // ); - // if edge == End { - // target += Duration::days(1) - // } - // fn increment_month(d: NaiveDateTime) -> NaiveDateTime { - // NaiveDateTime::new( - // NaiveDate::from_ymd( - // d.year() + (d.month() as i32 / 12), - // (d.month() + 1) % 12, - // d.day(), - // ), - // NaiveTime::from_hms(d.hour(), d.minute(), d.second()), - // ) - // } - // let dir_off = match dir { - // Forward => |d| d, - // Backward => increment_month, - // }; - // if target > from { - // Some(dir_off(target)) - // } else { - // Some(increment_month(dir_off(target))) - // } - todo!() - } - Property::Dayofweek => todo!(), - Property::Hour => { - let mut target = NaiveDateTime::new( - NaiveDate::from_ymd(from.year(), from.month(), from.day()), - NaiveTime::from_hms(value as u32, 0, 0), - ); - if edge == End { - target += Duration::hours(1) - } - let dir_off = match dir { - Forward => Duration::zero(), - Backward => Duration::days(-1), - }; - if target > from { - Some(target + dir_off) - } else { - Some(target + dir_off + Duration::days(1)) - } - } - Property::Minute => { - let mut target = NaiveDateTime::new( - NaiveDate::from_ymd(from.year(), from.month(), from.day()), - NaiveTime::from_hms(from.hour(), value as u32, 0), - ); - if edge == End { - target += Duration::minutes(1) - } - let dir_off = match dir { - Forward => Duration::zero(), - Backward => Duration::hours(-1), - }; - if target > from { - Some(target + dir_off) - } else { - Some(target + dir_off + Duration::hours(1)) - } - } - Property::Second => { - let mut target = NaiveDateTime::new( - NaiveDate::from_ymd(from.year(), from.month(), from.day()), - NaiveTime::from_hms(from.hour(), from.minute(), value as u32), - ); - if edge == End { - target += Duration::seconds(1) - } - let dir_off = match dir { - Forward => Duration::zero(), - Backward => Duration::minutes(-1), - }; - if target > from { - Some(target + dir_off) - } else { - Some(target + dir_off + Duration::minutes(1)) - } - } - Property::Unix => { - let geq = match dir { - Forward => |a, b| a >= b, - Backward => |a, b| a < b, - }; - if geq(from.timestamp(), (value + off) as i64) { - None - } else { - Some(NaiveDateTime::from_timestamp(value, 0)) - } - } - } - } - 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, Utc}; - use std::str::FromStr; - use Direction::*; - use Edge::*; - - #[test] - fn blub() { - let cond = Condition::And(vec![ - Condition::Equal { - modulus: None, - prop: Property::Monthofyear, - value: 1, - }, - Condition::Equal { - modulus: None, - prop: Property::Hour, - value: 12, - }, - ]); - // let cond = Condition::Equal { - // modulus: None, - // prop: Property::Hour, - // value: 12, - // }; - let dt = Utc::now().naive_utc(); - println!("START FORWARD => {:?}", cond.find(Start, Forward, dt)); - println!("END FORWARD => {:?}", cond.find(End, Forward, dt)); - println!("START BACKWARD => {:?}", cond.find(Start, Backward, dt)); - println!("END BACKWARD => {:?}", cond.find(End, Backward, dt)); - } - - #[test] - fn year_equal() { - 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); - } - - #[test] - fn month_equal() { - let cond = Condition::Equal { - modulus: None, - prop: Property::Monthofyear, - value: 3, - }; - - let dt = NaiveDateTime::from_str("2022-06-07T13:37:48").unwrap(); - - assert_eq!( - cond.find(Edge::Start, Direction::Forward, dt), - Some(NaiveDateTime::from_str("2023-04-01T00:00:00").unwrap()) - ); - assert_eq!( - cond.find(Edge::End, Direction::Forward, dt), - Some(NaiveDateTime::from_str("2023-05-01T00:00:00").unwrap()) - ); - assert_eq!( - cond.find(Edge::Start, Direction::Backward, dt), - Some(NaiveDateTime::from_str("2022-04-01T00:00:00").unwrap()) - ); - assert_eq!( - cond.find(Edge::End, Direction::Backward, dt), - Some(NaiveDateTime::from_str("2022-05-01T00:00:00").unwrap()) - ); - } -} |