diff options
author | Fredrik Meringdal <fredrikmeringdal@Fredriks-MacBook-Pro.local> | 2021-02-03 22:48:47 +0100 |
---|---|---|
committer | Fredrik Meringdal <fredrikmeringdal@Fredriks-MacBook-Pro.local> | 2021-02-03 22:48:47 +0100 |
commit | cc4ebe0e778298df981b38c853e58602946c98b6 (patch) | |
tree | 08659826241afc7994c5665572f589a391ee3145 | |
parent | bc16f6e7e6bbd145d1d0f541f98d74061f7fa966 (diff) | |
download | rust_rrule-cc4ebe0e778298df981b38c853e58602946c98b6.zip |
refactoring
-rw-r--r-- | src/iter/iter_v2.rs | 165 | ||||
-rw-r--r-- | src/iter/mod.rs | 136 | ||||
-rw-r--r-- | src/rrule.rs | 2 | ||||
-rw-r--r-- | src/rrule_iter.rs | 219 | ||||
-rw-r--r-- | src/rruleset_iter.rs | 2 |
5 files changed, 152 insertions, 372 deletions
diff --git a/src/iter/iter_v2.rs b/src/iter/iter_v2.rs deleted file mode 100644 index d2054f9..0000000 --- a/src/iter/iter_v2.rs +++ /dev/null @@ -1,165 +0,0 @@ -use std::cmp::{max, min}; - -use crate::{datetime::Time, Frequenzy}; -use chrono::prelude::*; -use chrono_tz::Tz; - -use super::{build_poslist, from_ordinal, increment_counter_date, remove_filtered_days, IterInfo}; - -pub struct RRuleIter { - pub counter_date: DateTime<Tz>, - pub ii: IterInfo, - pub timeset: Vec<Time>, - pub remain: Vec<DateTime<Tz>>, - pub finished: bool, -} - -impl Iterator for RRuleIter { - type Item = DateTime<Tz>; - - fn next(&mut self) -> Option<Self::Item> { - if self.finished { - return None; - } - - if !self.remain.is_empty() { - return Some(self.remain.remove(0)); - } - - generate(self); - - // println!("Done generating: {:?}", self.remain); - - if self.remain.is_empty() { - self.finished = true; - None - } else { - Some(self.remain.remove(0)) - } - } -} - -pub fn generate(iter: &mut RRuleIter) { - let options = iter.ii.options.clone(); - - match options.count { - Some(count) if count == 0 => return, - _ => (), - }; - - while iter.remain.is_empty() { - let (dayset, start, end) = iter.ii.getdayset( - &iter.ii.options.freq, - iter.counter_date.year() as isize, - iter.counter_date.month() as usize, - iter.counter_date.day() as usize, - ); - - let mut dayset = dayset - .into_iter() - .map(|s| Some(s as isize)) - .collect::<Vec<Option<isize>>>(); - - let filtered = remove_filtered_days(&mut dayset, start, end, &iter.ii); - - if options.bysetpos.len() > 0 { - let poslist = build_poslist( - &options.bysetpos, - &iter.timeset, - start, - end, - &iter.ii, - &dayset, - &options.tzid, - ); - - for j in 0..poslist.len() { - let res = poslist[j]; - if options.until.is_some() && res > options.until.unwrap() { - // return iter_result.get_value(); - continue; // or break ? - } - - if res >= options.dtstart { - iter.remain.push(res); - - if let Some(count) = iter.ii.options.count { - if count > 0 { - iter.ii.options.count = Some(count - 1); - } - // This means that the real count is 0, because of the decrement above - if count == 1 { - return; - } - } - } - } - } else { - for j in start..end { - let current_day = dayset[j]; - if current_day.is_none() { - continue; - } - - let current_day = current_day.unwrap(); - let date = - from_ordinal(iter.ii.yearordinal().unwrap() + current_day, &options.tzid); - for k in 0..iter.timeset.len() { - let res = options - .tzid - .ymd(date.year(), date.month(), date.day()) - .and_hms( - iter.timeset[k].hour as u32, - iter.timeset[k].minute as u32, - iter.timeset[k].second as u32, - ); - if options.until.is_some() && res > options.until.unwrap() { - return; - } - if res >= options.dtstart { - iter.remain.push(res); - - if let Some(count) = iter.ii.options.count { - if count > 0 { - iter.ii.options.count = Some(count - 1); - } - // This means that the real count is 0, because of the decrement above - if count == 1 { - return; - } - } - } - } - } - } - - if options.interval == 0 { - return; - } - - // Handle frequency and interval - iter.counter_date = increment_counter_date(iter.counter_date, &options, filtered); - - if iter.counter_date.year() > 2200 { - return; - } - - if options.freq == Frequenzy::Hourly - || options.freq == Frequenzy::Minutely - || options.freq == Frequenzy::Secondly - { - iter.timeset = iter.ii.gettimeset( - &options.freq, - iter.counter_date.hour() as usize, - iter.counter_date.minute() as usize, - iter.counter_date.second() as usize, - 0, - ); - } - - let year = iter.counter_date.year(); - let month = iter.counter_date.month(); - - iter.ii.rebuild(year as isize, month as usize); - } -} diff --git a/src/iter/mod.rs b/src/iter/mod.rs index 419dcbd..5fb439a 100644 --- a/src/iter/mod.rs +++ b/src/iter/mod.rs @@ -3,148 +3,16 @@ mod monthinfo; mod yearinfo; pub use iterinfo::IterInfo; mod poslist; -use poslist::build_poslist; +pub use poslist::build_poslist; mod easter; -mod iter_v2; mod masks; -pub use iter_v2::{generate, RRuleIter}; -use crate::datetime::{from_ordinal, get_weekday_val, DTime, Time}; +use crate::datetime::{get_weekday_val, DTime, Time}; use crate::options::*; use crate::utils::{includes, not_empty}; -use chrono::offset::TimeZone; use chrono::prelude::*; use chrono::Duration; -pub trait IterResult { - fn accept(&self, date: &DTime) -> (bool, bool); -} - -// pub fn iter<T: IterResult>(iter_result: &mut T, options: &mut ParsedOptions) -> Vec<DTime> { -// if (options.count.is_some() && options.count.unwrap() == 0) || options.interval == 0 { -// return iter_result.get_value(); -// } - -// let mut counter_date = options.dtstart; -// let mut ii = IterInfo::new(options); -// ii.rebuild(counter_date.year() as isize, counter_date.month() as usize); - -// let mut timeset = make_timeset(&ii, &counter_date, options); -// let mut count = match options.count { -// Some(count) => count, -// _ => 0, -// }; - -// loop { -// let (dayset, start, end) = ii.getdayset( -// &options.freq, -// counter_date.year() as isize, -// counter_date.month() as usize, -// counter_date.day() as usize, -// ); - -// let mut dayset = dayset -// .into_iter() -// .map(|s| Some(s as isize)) -// .collect::<Vec<Option<isize>>>(); - -// let filtered = remove_filtered_days(&mut dayset, start, end, &ii, options); - -// if not_empty(&options.bysetpos) { -// let poslist = build_poslist( -// &options.bysetpos, -// ×et, -// start, -// end, -// &ii, -// &dayset, -// &options.tzid, -// ); - -// for j in 0..poslist.len() { -// let res = poslist[j]; -// if options.until.is_some() && res > options.until.unwrap() { -// return iter_result.get_value(); -// } - -// if res >= options.dtstart { -// if !iter_result.accept(res) { -// return iter_result.get_value(); -// } - -// if count > 0 { -// count -= 1; -// if count == 0 { -// return iter_result.get_value(); -// } -// } -// } -// } -// } else { -// for j in start..end { -// let current_day = dayset[j]; -// if current_day.is_none() { -// continue; -// } - -// let current_day = current_day.unwrap(); -// let date = from_ordinal(ii.yearordinal().unwrap() + current_day, &options.tzid); -// for k in 0..timeset.len() { -// let res = options -// .tzid -// .ymd(date.year(), date.month(), date.day()) -// .and_hms( -// timeset[k].hour as u32, -// timeset[k].minute as u32, -// timeset[k].second as u32, -// ); -// if options.until.is_some() && res > options.until.unwrap() { -// return iter_result.get_value(); -// } -// if res >= options.dtstart { -// if !iter_result.accept(res) { -// return iter_result.get_value(); -// } - -// if count > 0 { -// count -= 1; -// if count == 0 { -// return iter_result.get_value(); -// } -// } -// } -// } -// } -// } - -// if options.interval == 0 { -// return iter_result.get_value(); -// } - -// // Handle frequency and interval -// counter_date = increment_counter_date(counter_date, options, filtered); - -// if counter_date.year() > 2200 { -// return iter_result.get_value(); -// } - -// if options.freq == Frequenzy::Hourly -// || options.freq == Frequenzy::Minutely -// || options.freq == Frequenzy::Secondly -// { -// timeset = ii.gettimeset( -// &options.freq, -// counter_date.hour() as usize, -// counter_date.minute() as usize, -// counter_date.second() as usize, -// 0, -// ); -// } - -// ii.rebuild(counter_date.year() as isize, counter_date.month() as usize); -// } -// } - pub fn increment_counter_date( counter_date: DTime, options: &ParsedOptions, diff --git a/src/rrule.rs b/src/rrule.rs index 0fa8f24..aa000d1 100644 --- a/src/rrule.rs +++ b/src/rrule.rs @@ -1,6 +1,4 @@ -use crate::iter::{generate, IterInfo}; use crate::options::*; -use crate::rrule_iter::*; use crate::rrulestr::build_rrule; use chrono::prelude::*; use chrono_tz::Tz; diff --git a/src/rrule_iter.rs b/src/rrule_iter.rs index 1b45a77..a3ead19 100644 --- a/src/rrule_iter.rs +++ b/src/rrule_iter.rs @@ -1,89 +1,168 @@ -use crate::{ - iter::{make_timeset, IterInfo, IterResult, RRuleIter}, - RRule, +use crate::iter::{ + build_poslist, increment_counter_date, make_timeset, remove_filtered_days, IterInfo, }; +use crate::{datetime::from_ordinal, RRule}; +use crate::{datetime::Time, Frequenzy}; use chrono::prelude::*; -use chrono::Duration; use chrono_tz::Tz; -pub enum QueryMethodTypes { - All, - Between, - Before, - After, +pub struct RRuleIter { + pub counter_date: DateTime<Tz>, + pub ii: IterInfo, + pub timeset: Vec<Time>, + pub remain: Vec<DateTime<Tz>>, + pub finished: bool, } -pub struct IterArgs { - pub inc: bool, - pub before: Option<DateTime<Tz>>, - pub after: Option<DateTime<Tz>>, - pub dt: Option<DateTime<Tz>>, -} +impl Iterator for RRuleIter { + type Item = DateTime<Tz>; -pub struct RRuleIterRes { - pub method: QueryMethodTypes, - pub args: IterArgs, - pub min_date: Option<DateTime<Tz>>, - pub max_date: Option<DateTime<Tz>>, - pub result: Vec<DateTime<Tz>>, - pub total: usize, -} + fn next(&mut self) -> Option<Self::Item> { + if self.finished { + return None; + } -impl RRuleIterRes { - pub fn new(method: QueryMethodTypes, args: IterArgs) -> Self { - let (max_date, min_date) = match method { - QueryMethodTypes::Between if args.inc => { - (Some(args.before.unwrap()), Some(args.after.unwrap())) - } - QueryMethodTypes::Between => ( - Some(args.before.unwrap() - Duration::milliseconds(1)), - Some(args.after.unwrap() + Duration::milliseconds(1)), - ), - QueryMethodTypes::Before if args.inc => (Some(args.dt.unwrap()), None), - QueryMethodTypes::Before => (Some(args.dt.unwrap() - Duration::milliseconds(1)), None), - QueryMethodTypes::After if args.inc => (None, Some(args.dt.unwrap())), - QueryMethodTypes::After => (None, Some(args.dt.unwrap() + Duration::milliseconds(1))), - _ => (None, None), - }; - - Self { - method, - args, - min_date, - max_date, - total: 0, - result: vec![], + if !self.remain.is_empty() { + return Some(self.remain.remove(0)); } - } - pub fn add(&mut self, date: DateTime<Tz>) -> bool { - self.result.push(date); - true + generate(self); + + // println!("Done generating: {:?}", self.remain); + + if self.remain.is_empty() { + self.finished = true; + None + } else { + Some(self.remain.remove(0)) + } } } -impl IterResult for RRuleIterRes { - // Returns tuple of flags indicating whether to add and continue - // iteration (add_date, continue_iteration) - fn accept(&self, date: &DateTime<Tz>) -> (bool, bool) { - let too_early = match self.min_date { - Some(d) => d > *date, - None => false, - }; - let too_late = match self.max_date { - Some(d) => d < *date, - None => false, - }; - match self.method { - QueryMethodTypes::Between if too_early => (false, true), - QueryMethodTypes::Between if too_late => (false, false), - QueryMethodTypes::Before if too_late => (false, false), - QueryMethodTypes::After => (!too_early, too_early), - _ => (true, true), +pub fn generate(iter: &mut RRuleIter) { + let options = iter.ii.options.clone(); + + match options.count { + Some(count) if count == 0 => return, + _ => (), + }; + + while iter.remain.is_empty() { + let (dayset, start, end) = iter.ii.getdayset( + &iter.ii.options.freq, + iter.counter_date.year() as isize, + iter.counter_date.month() as usize, + iter.counter_date.day() as usize, + ); + + let mut dayset = dayset + .into_iter() + .map(|s| Some(s as isize)) + .collect::<Vec<Option<isize>>>(); + + let filtered = remove_filtered_days(&mut dayset, start, end, &iter.ii); + + if options.bysetpos.len() > 0 { + let poslist = build_poslist( + &options.bysetpos, + &iter.timeset, + start, + end, + &iter.ii, + &dayset, + &options.tzid, + ); + + for j in 0..poslist.len() { + let res = poslist[j]; + if options.until.is_some() && res > options.until.unwrap() { + // return iter_result.get_value(); + continue; // or break ? + } + + if res >= options.dtstart { + iter.remain.push(res); + + if let Some(count) = iter.ii.options.count { + if count > 0 { + iter.ii.options.count = Some(count - 1); + } + // This means that the real count is 0, because of the decrement above + if count == 1 { + return; + } + } + } + } + } else { + for j in start..end { + let current_day = dayset[j]; + if current_day.is_none() { + continue; + } + + let current_day = current_day.unwrap(); + let date = + from_ordinal(iter.ii.yearordinal().unwrap() + current_day, &options.tzid); + for k in 0..iter.timeset.len() { + let res = options + .tzid + .ymd(date.year(), date.month(), date.day()) + .and_hms( + iter.timeset[k].hour as u32, + iter.timeset[k].minute as u32, + iter.timeset[k].second as u32, + ); + if options.until.is_some() && res > options.until.unwrap() { + return; + } + if res >= options.dtstart { + iter.remain.push(res); + + if let Some(count) = iter.ii.options.count { + if count > 0 { + iter.ii.options.count = Some(count - 1); + } + // This means that the real count is 0, because of the decrement above + if count == 1 { + return; + } + } + } + } + } + } + + if options.interval == 0 { + return; } + + // Handle frequency and interval + iter.counter_date = increment_counter_date(iter.counter_date, &options, filtered); + + if iter.counter_date.year() > 2200 { + return; + } + + if options.freq == Frequenzy::Hourly + || options.freq == Frequenzy::Minutely + || options.freq == Frequenzy::Secondly + { + iter.timeset = iter.ii.gettimeset( + &options.freq, + iter.counter_date.hour() as usize, + iter.counter_date.minute() as usize, + iter.counter_date.second() as usize, + 0, + ); + } + + let year = iter.counter_date.year(); + let month = iter.counter_date.month(); + + iter.ii.rebuild(year as isize, month as usize); } } - impl IntoIterator for RRule { type Item = DateTime<Tz>; diff --git a/src/rruleset_iter.rs b/src/rruleset_iter.rs index 5dc70c6..6cd207a 100644 --- a/src/rruleset_iter.rs +++ b/src/rruleset_iter.rs @@ -1,5 +1,5 @@ use crate::rruleset::RRuleSet; -use crate::{iter::RRuleIter, RRule}; +use crate::{rrule_iter::RRuleIter, RRule}; use chrono::prelude::*; use chrono_tz::Tz; use std::collections::HashMap; |