summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorFredrik Meringdal <fmeringdal@hotmail.com>2020-10-20 22:08:19 +0200
committerFredrik Meringdal <fmeringdal@hotmail.com>2020-10-20 22:08:19 +0200
commiteac4ef5fe5f0b86b576736ea49b53043c24c1357 (patch)
tree900d6ef011340e424949de496fd59dbf64bfd7a1 /src
parentcda2ac25b9e5f091f354dccabd86d97c19c4ccde (diff)
downloadrust_rrule-eac4ef5fe5f0b86b576736ea49b53043c24c1357.zip
some refactoring and it works
Diffstat (limited to 'src')
-rw-r--r--src/iter.rs11
-rw-r--r--src/iter_set.rs405
-rw-r--r--src/options.rs4
-rw-r--r--src/rrule.rs3
-rw-r--r--src/rruleset.rs348
5 files changed, 361 insertions, 410 deletions
diff --git a/src/iter.rs b/src/iter.rs
index d777df7..8a47002 100644
--- a/src/iter.rs
+++ b/src/iter.rs
@@ -18,8 +18,7 @@ pub struct IterArgs {
pub inc: bool,
pub before: DateTime<Tz>,
pub after: DateTime<Tz>,
- pub dt: DateTime<Tz>,
- pub _value: Option<Vec<DateTime<Utc>>>,
+ pub dt: DateTime<Tz>
}
pub struct IterResult {
@@ -27,7 +26,7 @@ pub struct IterResult {
pub args: IterArgs,
pub min_date: Option<DateTime<Tz>>,
pub max_date: Option<DateTime<Tz>>,
- pub _result: Vec<DateTime<Tz>>,
+ pub result: Vec<DateTime<Tz>>,
pub total: usize,
}
@@ -52,7 +51,7 @@ impl IterResult {
min_date,
max_date,
total: 0,
- _result: vec![],
+ result: vec![],
}
}
@@ -75,12 +74,12 @@ impl IterResult {
}
pub fn add(&mut self, date: DateTime<Tz>) -> bool {
- self._result.push(date);
+ self.result.push(date);
true
}
pub fn get_value(&self) -> Vec<DateTime<Tz>> {
- self._result.clone()
+ self.result.clone()
//match self.method {
//QueryMethodTypes::BETWEEN => Some(self._result.clone()),
//_ => {
diff --git a/src/iter_set.rs b/src/iter_set.rs
index 4cc864c..a8a7e48 100644
--- a/src/iter_set.rs
+++ b/src/iter_set.rs
@@ -9,122 +9,12 @@ use chrono::{DateTime, Duration, Utc};
use chrono_tz::*;
use std::collections::HashMap;
-pub fn eval_exdate(
- after: &DateTime<Tz>,
- before: &DateTime<Tz>,
- exrule: &mut Vec<RRule>,
- exdate_hash: &mut HashMap<i64, bool>,
-) {
- for rrule in exrule.iter_mut() {
- for date in rrule.between(after, before, true) {
- exdate_hash.insert(date.timestamp(), true);
- }
- }
-}
-
-fn accept_1(
- date: DateTime<Tz>,
- exdate_hash: &mut HashMap<i64, bool>,
- exrule: &mut Vec<RRule>,
- iter_res: &mut IterResult,
-) -> bool {
- println!("Accept 1");
- println!("Exdates: {:?}", exdate_hash);
- let dt = date.timestamp();
- if !exdate_hash.contains_key(&dt) {
- eval_exdate(
- &UTC.timestamp(dt - 1, 0),
- &UTC.timestamp(dt + 1, 0),
- exrule,
- exdate_hash,
- );
- if !exdate_hash.contains_key(&dt) {
- exdate_hash.insert(dt, true);
- return iter_res.accept(date.clone());
- }
- }
-
- true
-}
-
-fn accept_2(
- date: DateTime<Tz>,
- exdate_hash: &mut HashMap<i64, bool>,
- iter_res: &mut IterResult,
-) -> bool {
- let dt = date.timestamp();
- if !exdate_hash.contains_key(&dt) {
- if !exdate_hash.contains_key(&dt) {
- exdate_hash.insert(dt, true);
- return iter_res.accept(date.clone());
- }
- }
-
- true
-}
-
-pub fn iter_set(
- iter_res: &mut IterResult,
- mut rrule: Vec<RRule>,
- mut exrule: Vec<RRule>,
- rdate: Vec<DateTime<Utc>>,
- exdate: Vec<DateTime<Utc>>,
- tzid: Option<String>,
-) -> Vec<DateTime<Tz>> {
- let tzid: Tz = tzid.unwrap_or(String::from("UTC")).parse().unwrap_or(UTC);
-
- let mut exdate_hash = HashMap::new();
-
- for date in &exdate {
- let zoned_date = date.with_timezone(&tzid);
- exdate_hash.insert(zoned_date.timestamp(), true);
- }
-
- match iter_res.method {
- QueryMethodTypes::BETWEEN => {
- eval_exdate(
- &iter_res.args.after,
- &iter_res.args.before,
- &mut exrule,
- &mut exdate_hash,
- );
- }
- _ => (),
- };
-
- for date in &rdate {
- let zoned_date = date.with_timezone(&tzid);
- println!("Zoned date: {:?}", zoned_date);
-
- match iter_res.method {
- QueryMethodTypes::BETWEEN => {
- if !accept_2(zoned_date, &mut exdate_hash, iter_res) {
- break;
- }
- }
- _ => {
- if !accept_1(zoned_date, &mut exdate_hash, &mut exrule, iter_res) {
- break;
- }
- }
- };
- }
-
- for rule in rrule.iter_mut() {
- iter_v2(iter_res, &mut rule.options, &mut exdate_hash, &mut exrule);
- }
-
- let mut res = iter_res._result.clone();
- res.sort();
- res
-}
-
-pub fn iter_v2(
+pub fn iter_v2<F: FnMut(DateTime<Tz>, &mut IterResult) -> bool>(
iter_result: &mut IterResult,
options: &mut ParsedOptions,
- exdate_hash: &mut HashMap<i64, bool>,
- exrule: &mut Vec<RRule>,
+ mut accept: F
) -> Vec<DateTime<Tz>> {
+
if (options.count.is_some() && options.count.unwrap() == 0) || options.interval == 0 {
return iter_result.get_value();
}
@@ -167,14 +57,7 @@ pub fn iter_v2(
//let rezoned_date = rezone_if_needed(&res, &options);
let rezoned_date = UTC.timestamp(res.timestamp(), 0);
- let accepted = match iter_result.method {
- QueryMethodTypes::BETWEEN => {
- accept_2(rezoned_date, exdate_hash, iter_result)
- }
- _ => accept_1(rezoned_date, exdate_hash, exrule, iter_result),
- };
-
- if !accepted {
+ if !accept(rezoned_date, iter_result) {
return iter_result.get_value();
}
@@ -208,19 +91,7 @@ pub fn iter_v2(
//let rezoned_date = rezone_if_needed(&res, &options);
let rezoned_date = UTC.timestamp(res.timestamp(), 0);
- if rezoned_date.day() == 2 {
- println!("yoooooooooooooooooooooooo");
- println!("iter date ts: {}", rezoned_date.timestamp());
- println!("Ex dates: {:?}", exdate_hash);
- }
-
- let accepted = match iter_result.method {
- QueryMethodTypes::BETWEEN => {
- accept_2(rezoned_date, exdate_hash, iter_result)
- }
- _ => accept_1(rezoned_date, exdate_hash, exrule, iter_result),
- };
- if !accepted {
+ if !accept(rezoned_date, iter_result) {
return iter_result.get_value();
}
if count > 0 {
@@ -262,269 +133,3 @@ pub fn iter_v2(
}
}
-#[cfg(test)]
-mod test_iter_set {
- use super::*;
-
- fn ymd_hms(
- year: i32,
- month: u32,
- day: u32,
- hour: u32,
- minute: u32,
- second: u32,
- ) -> DateTime<Utc> {
- Utc.ymd(year, month, day).and_hms(hour, minute, second)
- }
-
- fn ymd_hms_2(
- year: i32,
- month: u32,
- day: u32,
- hour: u32,
- minute: u32,
- second: u32,
- ) -> DateTime<Tz> {
- UTC.ymd(year, month, day).and_hms(hour, minute, second)
- }
-
- fn test_recurring(actual_dates: Vec<DateTime<Tz>>, expected_dates: Vec<DateTime<Tz>>) {
- assert_eq!(
- actual_dates.len(),
- expected_dates.len(),
- "Expected number of returned dates to be equal to the expected"
- );
-
- println!("Acutal: {:?}", actual_dates);
- for (actual, exptected) in actual_dates.into_iter().zip(expected_dates) {
- assert_eq!(actual, exptected);
- }
- }
-
- #[test]
- fn rrule_and_exrule() {
- let iter_args = IterArgs {
- inc: true,
- before: UTC.ymd(2020, 1, 1).and_hms(0, 0, 0),
- after: UTC.ymd(2020, 1, 1).and_hms(0, 0, 0),
- dt: UTC.ymd(2020, 1, 1).and_hms(0, 0, 0),
- _value: Some(vec![]),
- };
- let mut iter_res = IterResult::new(QueryMethodTypes::ALL, iter_args);
-
- let mut options1 = ParsedOptions {
- freq: Frequenzy::YEARLY,
- count: Some(6),
- bymonth: vec![],
- dtstart: Utc.ymd(1997, 9, 2).and_hms(9, 0, 0),
- byweekday: vec![1, 3],
- byhour: vec![9],
- bysetpos: vec![],
- byweekno: vec![],
- byminute: vec![0],
- bysecond: vec![0],
- byyearday: vec![],
- bymonthday: vec![],
- bynweekday: vec![],
- bynmonthday: vec![],
- until: None,
- wkst: 0,
- tzid: None,
- interval: 1,
- byeaster: None,
- };
- let rrule1 = RRule::new(options1);
- let mut options2 = ParsedOptions {
- freq: Frequenzy::YEARLY,
- count: Some(3),
- bymonth: vec![],
- dtstart: Utc.ymd(1997, 9, 2).and_hms(9, 0, 0),
- byweekday: vec![3],
- byhour: vec![9],
- bysetpos: vec![],
- byweekno: vec![],
- byminute: vec![0],
- bysecond: vec![0],
- byyearday: vec![],
- bymonthday: vec![],
- bynweekday: vec![],
- bynmonthday: vec![],
- until: None,
- wkst: 0,
- tzid: None,
- interval: 1,
- byeaster: None,
- };
- let rrule2 = RRule::new(options2);
-
- let res = iter_set(
- &mut iter_res,
- vec![rrule1],
- vec![rrule2],
- vec![],
- vec![],
- None,
- );
- test_recurring(
- res,
- vec![
- ymd_hms_2(1997, 9, 2, 9, 0, 0),
- ymd_hms_2(1997, 9, 9, 9, 0, 0),
- ymd_hms_2(1997, 9, 16, 9, 0, 0),
- ],
- );
- }
-
- #[test]
- fn setdate_and_exdate() {
- let iter_args = IterArgs {
- inc: true,
- before: UTC.ymd(2020, 1, 1).and_hms(0, 0, 0),
- after: UTC.ymd(2020, 1, 1).and_hms(0, 0, 0),
- dt: UTC.ymd(2020, 1, 1).and_hms(0, 0, 0),
- _value: Some(vec![]),
- };
- let mut iter_res = IterResult::new(QueryMethodTypes::ALL, iter_args);
-
- let res = iter_set(
- &mut iter_res,
- vec![],
- vec![],
- vec![
- ymd_hms(1997, 9, 2, 9, 0, 0),
- ymd_hms(1997, 9, 4, 9, 0, 0),
- ymd_hms(1997, 9, 9, 9, 0, 0),
- ymd_hms(1997, 9, 11, 9, 0, 0),
- ymd_hms(1997, 9, 16, 9, 0, 0),
- ymd_hms(1997, 9, 18, 9, 0, 0),
- ],
- vec![
- ymd_hms(1997, 9, 4, 9, 0, 0),
- ymd_hms(1997, 9, 11, 9, 0, 0),
- ymd_hms(1997, 9, 18, 9, 0, 0),
- ],
- None,
- );
- test_recurring(
- res,
- vec![
- ymd_hms_2(1997, 9, 2, 9, 0, 0),
- ymd_hms_2(1997, 9, 9, 9, 0, 0),
- ymd_hms_2(1997, 9, 16, 9, 0, 0),
- ],
- );
- }
-
- #[test]
- fn setdate_and_exrule() {
- let iter_args = IterArgs {
- inc: true,
- before: UTC.ymd(2020, 1, 1).and_hms(0, 0, 0),
- after: UTC.ymd(2020, 1, 1).and_hms(0, 0, 0),
- dt: UTC.ymd(2020, 1, 1).and_hms(0, 0, 0),
- _value: Some(vec![]),
- };
- let mut iter_res = IterResult::new(QueryMethodTypes::ALL, iter_args);
-
- let mut options = ParsedOptions {
- freq: Frequenzy::YEARLY,
- count: Some(3),
- bymonth: vec![],
- dtstart: Utc.ymd(1997, 9, 2).and_hms(9, 0, 0),
- byweekday: vec![3],
- byhour: vec![9],
- bysetpos: vec![],
- byweekno: vec![],
- byminute: vec![0],
- bysecond: vec![0],
- byyearday: vec![],
- bymonthday: vec![],
- bynweekday: vec![],
- bynmonthday: vec![],
- until: None,
- wkst: 0,
- tzid: None,
- interval: 1,
- byeaster: None,
- };
- let exrrule = RRule::new(options);
- let res = iter_set(
- &mut iter_res,
- vec![],
- vec![exrrule],
- vec![
- ymd_hms(1997, 9, 2, 9, 0, 0),
- ymd_hms(1997, 9, 4, 9, 0, 0),
- ymd_hms(1997, 9, 9, 9, 0, 0),
- ymd_hms(1997, 9, 11, 9, 0, 0),
- ymd_hms(1997, 9, 16, 9, 0, 0),
- ymd_hms(1997, 9, 18, 9, 0, 0),
- ],
- vec![],
- None,
- );
- test_recurring(
- res,
- vec![
- ymd_hms_2(1997, 9, 2, 9, 0, 0),
- ymd_hms_2(1997, 9, 9, 9, 0, 0),
- ymd_hms_2(1997, 9, 16, 9, 0, 0),
- ],
- );
- }
-
- #[test]
- fn rrule_and_exdate() {
- let iter_args = IterArgs {
- inc: true,
- before: UTC.ymd(2020, 1, 1).and_hms(0, 0, 0),
- after: UTC.ymd(2020, 1, 1).and_hms(0, 0, 0),
- dt: UTC.ymd(2020, 1, 1).and_hms(0, 0, 0),
- _value: Some(vec![]),
- };
- let mut iter_res = IterResult::new(QueryMethodTypes::ALL, iter_args);
-
- let mut options = ParsedOptions {
- freq: Frequenzy::YEARLY,
- count: Some(6),
- bymonth: vec![],
- dtstart: Utc.ymd(1997, 9, 2).and_hms(9, 0, 0),
- byweekday: vec![1, 3],
- byhour: vec![9],
- bysetpos: vec![],
- byweekno: vec![],
- byminute: vec![0],
- bysecond: vec![0],
- byyearday: vec![],
- bymonthday: vec![],
- bynweekday: vec![],
- bynmonthday: vec![],
- until: None,
- wkst: 0,
- tzid: None,
- interval: 1,
- byeaster: None,
- };
- let rrule = RRule::new(options);
- let res = iter_set(
- &mut iter_res,
- vec![rrule],
- vec![],
- vec![],
- vec![
- ymd_hms(1997, 9, 2, 9, 0, 0),
- ymd_hms(1997, 9, 4, 9, 0, 0),
- ymd_hms(1997, 9, 9, 9, 0, 0),
- ],
- None,
- );
- test_recurring(
- res,
- vec![
- ymd_hms_2(1997, 9, 11, 9, 0, 0),
- ymd_hms_2(1997, 9, 16, 9, 0, 0),
- ymd_hms_2(1997, 9, 18, 9, 0, 0),
- ],
- );
- }
-}
diff --git a/src/options.rs b/src/options.rs
index 59f1c43..c3aeff3 100644
--- a/src/options.rs
+++ b/src/options.rs
@@ -14,7 +14,7 @@ pub struct YearInfo {
pub wnomask: Option<Vec<usize>>,
}
-#[derive(Debug, PartialEq, PartialOrd)]
+#[derive(Debug, PartialEq, PartialOrd, Clone)]
pub enum Frequenzy {
YEARLY = 0,
MONTHLY = 1,
@@ -25,7 +25,7 @@ pub enum Frequenzy {
SECONDLY = 6,
}
-#[derive(Debug)]
+#[derive(Debug, Clone)]
pub struct ParsedOptions {
pub freq: Frequenzy,
pub interval: usize,
diff --git a/src/rrule.rs b/src/rrule.rs
index 92b2ba5..53ccf39 100644
--- a/src/rrule.rs
+++ b/src/rrule.rs
@@ -3,6 +3,7 @@ use crate::options::*;
use chrono::prelude::*;
use chrono_tz::{Tz, UTC};
+#[derive(Clone, Debug)]
pub struct RRule {
cache: bool,
pub options: ParsedOptions,
@@ -26,7 +27,6 @@ impl RRule {
before: UTC.ymd(2020, 1, 1).and_hms(0, 0, 0),
after: UTC.ymd(2020, 1, 1).and_hms(0, 0, 0),
dt: UTC.ymd(2020, 1, 1).and_hms(0, 0, 0),
- _value: Some(vec![]),
};
let mut iter_res = IterResult::new(QueryMethodTypes::ALL, iter_args);
@@ -45,7 +45,6 @@ impl RRule {
before: before.clone(),
after: after.clone(),
dt: UTC.ymd(2020, 1, 1).and_hms(0, 0, 0),
- _value: Some(vec![]),
};
let mut iter_res = IterResult::new(QueryMethodTypes::ALL, iter_args);
diff --git a/src/rruleset.rs b/src/rruleset.rs
index fe8a723..a725ae5 100644
--- a/src/rruleset.rs
+++ b/src/rruleset.rs
@@ -1,5 +1,10 @@
use crate::rrule::*;
use chrono::prelude::*;
+use chrono_tz::{Tz, UTC};
+use crate::options::*;
+use crate::iter_set::iter_v2;
+use crate::iter::*;
+use std::collections::HashMap;
struct RRuleSet {
rrule: Vec<RRule>,
@@ -7,6 +12,11 @@ struct RRuleSet {
exrule: Vec<RRule>,
exdate: Vec<DateTime<Utc>>,
dtstart: Option<DateTime<Utc>>,
+ exdate_hash: HashMap<i64, ()>
+}
+
+struct RRuleIter {
+
}
impl RRuleSet {
@@ -17,6 +27,7 @@ impl RRuleSet {
exrule: vec![],
exdate: vec![],
dtstart: None,
+ exdate_hash: HashMap::new()
}
}
@@ -36,6 +47,19 @@ impl RRuleSet {
self.exdate.push(exdate);
}
+ pub fn all(&mut self) -> Vec<DateTime<Tz>> {
+
+ let iter_args = IterArgs {
+ inc: true,
+ before: UTC.ymd(2020, 1, 1).and_hms(0, 0, 0),
+ after: UTC.ymd(2020, 1, 1).and_hms(0, 0, 0),
+ dt: UTC.ymd(2020, 1, 1).and_hms(0, 0, 0),
+ };
+ let mut iter_res = IterResult::new(QueryMethodTypes::ALL, iter_args);
+
+ self.iter(&mut iter_res, None)
+ }
+
pub fn value_of(&mut self) -> Vec<String> {
let mut result = vec![];
@@ -72,4 +96,328 @@ impl RRuleSet {
result
}
+
+ pub fn eval_exdate(
+ &mut self,
+ after: &DateTime<Tz>,
+ before: &DateTime<Tz>,
+ ) {
+ for rrule in self.exrule.iter_mut() {
+ for date in rrule.between(after, before, true) {
+ self.exdate_hash.insert(date.timestamp(), ());
+ }
+ }
+ }
+
+
+ fn accept_2(
+ &mut self,
+ date: DateTime<Tz>,
+ iter_res: &mut IterResult,
+ ) -> bool {
+ let dt = date.timestamp();
+ if !self.exdate_hash.contains_key(&dt) {
+ self.eval_exdate(
+ &UTC.timestamp(dt - 1, 0),
+ &UTC.timestamp(dt + 1, 0),
+ );
+ if !self.exdate_hash.contains_key(&dt) {
+ self.exdate_hash.insert(dt, ());
+ return iter_res.accept(date.clone());
+ }
+ }
+
+ true
+ }
+
+ fn accept_1(
+ &mut self,
+ date: DateTime<Tz>,
+ iter_res: &mut IterResult,
+ ) -> bool {
+ let dt = date.timestamp();
+ if !self.exdate_hash.contains_key(&dt) {
+ if !self.exdate_hash.contains_key(&dt) {
+ self.exdate_hash.insert(dt, ());
+ return iter_res.accept(date.clone());
+ }
+ }
+
+ true
+ }
+
+ fn accept(
+ &mut self,
+ date: DateTime<Tz>,
+ iter_res: &mut IterResult) -> bool {
+ match &iter_res.method {
+ QueryMethodTypes::BETWEEN => self.accept_1(date, iter_res),
+ _ => self.accept_2(date, iter_res),
+ }
+ }
+
+
+ fn iter(
+ &mut self,
+ iter_res: &mut IterResult,
+ tzid: Option<String>,
+ ) -> Vec<DateTime<Tz>> {
+ let tzid: Tz = tzid.unwrap_or(String::from("UTC")).parse().unwrap_or(UTC);
+
+ for date in &self.exdate {
+ let zoned_date = date.with_timezone(&tzid);
+ self.exdate_hash.insert(zoned_date.timestamp(), ());
+ }
+
+ match iter_res.method {
+ QueryMethodTypes::BETWEEN => {
+ self.eval_exdate(
+ &iter_res.args.after,
+ &iter_res.args.before,
+ );
+ }
+ _ => (),
+ };
+
+ for date in &self.rdate.clone() {
+ let zoned_date = date.with_timezone(&tzid);
+ if !self.accept(zoned_date, iter_res){
+ break;
+ }
+ }
+
+ for rule in self.rrule.clone().iter_mut() {
+ iter_v2(iter_res, &mut rule.options, |date: DateTime<Tz>, iter_res: &mut IterResult| {
+ self.accept(date, iter_res)
+ });
+ }
+
+ let mut res = iter_res.get_value();
+ res.sort();
+ res
+ }
+}
+
+
+#[cfg(test)]
+mod test_iter_set {
+ use super::*;
+
+ fn ymd_hms(
+ year: i32,
+ month: u32,
+ day: u32,
+ hour: u32,
+ minute: u32,
+ second: u32,
+ ) -> DateTime<Utc> {
+ Utc.ymd(year, month, day).and_hms(hour, minute, second)
+ }
+
+ fn ymd_hms_2(
+ year: i32,
+ month: u32,
+ day: u32,
+ hour: u32,
+ minute: u32,
+ second: u32,
+ ) -> DateTime<Tz> {
+ UTC.ymd(year, month, day).and_hms(hour, minute, second)
+ }
+
+ fn test_recurring(actual_dates: Vec<DateTime<Tz>>, expected_dates: Vec<DateTime<Tz>>) {
+ assert_eq!(
+ actual_dates.len(),
+ expected_dates.len(),
+ "Expected number of returned dates to be equal to the expected"
+ );
+
+ println!("Acutal: {:?}", actual_dates);
+ for (actual, exptected) in actual_dates.into_iter().zip(expected_dates) {
+ assert_eq!(actual, exptected);
+ }
+ }
+
+ #[test]
+ fn rrule_and_exrule() {
+
+ let mut set = RRuleSet::new();
+
+ let mut options1 = ParsedOptions {
+ freq: Frequenzy::YEARLY,
+ count: Some(6),
+ bymonth: vec![],
+ dtstart: Utc.ymd(1997, 9, 2).and_hms(9, 0, 0),
+ byweekday: vec![1, 3],
+ byhour: vec![9],
+ bysetpos: vec![],
+ byweekno: vec![],
+ byminute: vec![0],
+ bysecond: vec![0],
+ byyearday: vec![],
+ bymonthday: vec![],
+ bynweekday: vec![],
+ bynmonthday: vec![],
+ until: None,
+ wkst: 0,
+ tzid: None,
+ interval: 1,
+ byeaster: None,
+ };
+ let rrule = RRule::new(options1);
+ set.rrule(rrule);
+ let mut options2 = ParsedOptions {
+ freq: Frequenzy::YEARLY,
+ count: Some(3),
+ bymonth: vec![],
+ dtstart: Utc.ymd(1997, 9, 2).and_hms(9, 0, 0),
+ byweekday: vec![3],
+ byhour: vec![9],
+ bysetpos: vec![],
+ byweekno: vec![],
+ byminute: vec![0],
+ bysecond: vec![0],
+ byyearday: vec![],
+ bymonthday: vec![],
+ bynweekday: vec![],
+ bynmonthday: vec![],
+ until: None,
+ wkst: 0,
+ tzid: None,
+ interval: 1,
+ byeaster: None,
+ };
+ let exrule = RRule::new(options2);
+ set.exrule(exrule);
+
+ test_recurring(
+ set.all(),
+ vec![
+ ymd_hms_2(1997, 9, 2, 9, 0, 0),
+ ymd_hms_2(1997, 9, 9, 9, 0, 0),
+ ymd_hms_2(1997, 9, 16, 9, 0, 0),
+ ],
+ );
+ }
+
+ #[test]
+ fn setdate_and_exdate() {
+
+ let mut set = RRuleSet::new();
+
+ set.rdate(ymd_hms(1997, 9, 2, 9, 0, 0));
+ set.rdate(ymd_hms(1997, 9, 4, 9, 0, 0));
+ set.rdate(ymd_hms(1997, 9, 9, 9, 0, 0));
+ set.rdate(ymd_hms(1997, 9, 11, 9, 0, 0));
+ set.rdate(ymd_hms(1997, 9, 16, 9, 0, 0));
+ set.rdate(ymd_hms(1997, 9, 18, 9, 0, 0));
+
+ set.exdate(ymd_hms(1997, 9, 4, 9, 0, 0));
+ set.exdate(ymd_hms(1997, 9, 11, 9, 0, 0));
+ set.exdate(ymd_hms(1997, 9, 18, 9, 0, 0));
+
+
+ test_recurring(
+ set.all(),
+ vec![
+ ymd_hms_2(1997, 9, 2, 9, 0, 0),
+ ymd_hms_2(1997, 9, 9, 9, 0, 0),
+ ymd_hms_2(1997, 9, 16, 9, 0, 0),
+ ],
+ );
+ }
+
+ #[test]
+ fn setdate_and_exrule() {
+
+
+
+ let mut set = RRuleSet::new();
+
+ set.rdate(ymd_hms(1997, 9, 2, 9, 0, 0));
+ set.rdate(ymd_hms(1997, 9, 4, 9, 0, 0));
+ set.rdate(ymd_hms(1997, 9, 9, 9, 0, 0));
+ set.rdate(ymd_hms(1997, 9, 11, 9, 0, 0));
+ set.rdate(ymd_hms(1997, 9, 16, 9, 0, 0));
+ set.rdate(ymd_hms(1997, 9, 18, 9, 0, 0));
+
+
+ let mut options = ParsedOptions {
+ freq: Frequenzy::YEARLY,
+ count: Some(3),
+ bymonth: vec![],
+ dtstart: Utc.ymd(1997, 9, 2).and_hms(9, 0, 0),
+ byweekday: vec![3],
+ byhour: vec![9],
+ bysetpos: vec![],
+ byweekno: vec![],
+ byminute: vec![0],
+ bysecond: vec![0],
+ byyearday: vec![],
+ bymonthday: vec![],
+ bynweekday: vec![],
+ bynmonthday: vec![],
+ until: None,
+ wkst: 0,
+ tzid: None,
+ interval: 1,
+ byeaster: None,
+ };
+ let exrrule = RRule::new(options);
+ set.exrule(exrrule);
+
+ test_recurring(
+ set.all(),
+ vec![
+ ymd_hms_2(1997, 9, 2, 9, 0, 0),
+ ymd_hms_2(1997, 9, 9, 9, 0, 0),
+ ymd_hms_2(1997, 9, 16, 9, 0, 0),
+ ],
+ );
+ }
+
+ #[test]
+ fn rrule_and_exdate() {
+
+
+ let mut set = RRuleSet::new();
+
+ let mut options = ParsedOptions {
+ freq: Frequenzy::YEARLY,
+ count: Some(6),
+ bymonth: vec![],
+ dtstart: Utc.ymd(1997, 9, 2).and_hms(9, 0, 0),
+ byweekday: vec![1, 3],
+ byhour: vec![9],
+ bysetpos: vec![],
+ byweekno: vec![],
+ byminute: vec![0],
+ bysecond: vec![0],
+ byyearday: vec![],
+ bymonthday: vec![],
+ bynweekday: vec![],
+ bynmonthday: vec![],
+ until: None,
+ wkst: 0,
+ tzid: None,
+ interval: 1,
+ byeaster: None,
+ };
+ let rrule = RRule::new(options);
+ set.rrule(rrule);
+
+ set.exdate(ymd_hms(1997, 9, 2, 9, 0, 0));
+ set.exdate(ymd_hms(1997, 9, 4, 9, 0, 0));
+ set.exdate(ymd_hms(1997, 9, 9, 9, 0, 0));
+
+
+ test_recurring(
+ set.all(),
+ vec![
+ ymd_hms_2(1997, 9, 11, 9, 0, 0),
+ ymd_hms_2(1997, 9, 16, 9, 0, 0),
+ ymd_hms_2(1997, 9, 18, 9, 0, 0),
+ ],
+ );
+ }
}