summaryrefslogtreecommitdiff
path: root/src/iter
diff options
context:
space:
mode:
Diffstat (limited to 'src/iter')
-rw-r--r--src/iter/iter_v2.rs151
-rw-r--r--src/iter/iterinfo.rs12
-rw-r--r--src/iter/mod.rs258
3 files changed, 286 insertions, 135 deletions
diff --git a/src/iter/iter_v2.rs b/src/iter/iter_v2.rs
new file mode 100644
index 0000000..609206d
--- /dev/null
+++ b/src/iter/iter_v2.rs
@@ -0,0 +1,151 @@
+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 {
+ generate(self);
+ }
+
+ if self.remain.is_empty() {
+ return None;
+ }
+
+ Some(self.remain.remove(0))
+ }
+}
+
+pub fn generate(iter: &mut RRuleIter) {
+ let options = iter.ii.options;
+ let count = options.count.unwrap_or(0);
+
+ 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 count > 0 {
+ count -= 1;
+ if count == 0 {
+ 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);
+ // let (add, continue_iterator) = iter_result.accept(&res);
+ // if add {
+ // iter.remain.push(res);
+ // }
+ // if !continue_iterator {
+ // return;
+ // }
+
+ if count > 0 {
+ count -= 1;
+ if count == 0 {
+ 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,
+ );
+ }
+
+ iter.ii.rebuild(
+ iter.counter_date.year() as isize,
+ iter.counter_date.month() as usize,
+ );
+ }
+}
diff --git a/src/iter/iterinfo.rs b/src/iter/iterinfo.rs
index 7c47645..048632b 100644
--- a/src/iter/iterinfo.rs
+++ b/src/iter/iterinfo.rs
@@ -5,15 +5,15 @@ use crate::iter::yearinfo::{rebuild_year, YearInfo};
use crate::options::{Frequenzy, ParsedOptions};
use chrono::prelude::*;
-pub struct IterInfo<'a> {
+pub struct IterInfo {
pub yearinfo: Option<YearInfo>,
pub monthinfo: Option<MonthInfo>,
pub eastermask: Option<Vec<isize>>,
- options: &'a ParsedOptions,
+ pub options: ParsedOptions,
}
-impl<'a> IterInfo<'a> {
- pub fn new(options: &'a ParsedOptions) -> Self {
+impl IterInfo {
+ pub fn new(options: ParsedOptions) -> Self {
Self {
options,
yearinfo: None,
@@ -24,7 +24,7 @@ impl<'a> IterInfo<'a> {
pub fn rebuild(&mut self, year: isize, month: usize) {
if self.monthinfo.is_none() || year != self.monthinfo.as_ref().unwrap().lastyear {
- self.yearinfo = Some(rebuild_year(year as i32, self.options));
+ self.yearinfo = Some(rebuild_year(year as i32, &self.options));
}
if !self.options.bynweekday.is_empty()
@@ -38,7 +38,7 @@ impl<'a> IterInfo<'a> {
yearinfo.yearlen,
&yearinfo.mrange,
&yearinfo.wdaymask,
- self.options,
+ &self.options,
));
}
}
diff --git a/src/iter/mod.rs b/src/iter/mod.rs
index dc7c51d..419dcbd 100644
--- a/src/iter/mod.rs
+++ b/src/iter/mod.rs
@@ -1,11 +1,13 @@
mod iterinfo;
mod monthinfo;
mod yearinfo;
-use iterinfo::IterInfo;
+pub use iterinfo::IterInfo;
mod poslist;
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::options::*;
@@ -15,134 +17,133 @@ use chrono::prelude::*;
use chrono::Duration;
pub trait IterResult {
- fn accept(&mut self, date: DTime) -> bool;
- fn get_value(&self) -> Vec<DTime>;
+ 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,
- &timeset,
- 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 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,
+// &timeset,
+// 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,
@@ -301,14 +302,13 @@ pub fn remove_filtered_days(
start: usize,
end: usize,
ii: &IterInfo,
- options: &ParsedOptions,
) -> bool {
let mut filtered = false;
for daycounter in start..end {
match dayset[daycounter] {
Some(current_day) => {
- filtered = is_filtered(ii, current_day as usize, options);
+ filtered = is_filtered(ii, current_day as usize, &ii.options);
if filtered {
dayset[daycounter] = None;
}