summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFredrik Meringdal <fmeringdal@hotmail.com>2020-11-13 19:53:44 +0100
committerFredrik Meringdal <fmeringdal@hotmail.com>2020-11-13 19:53:44 +0100
commit05e9450ea926833d2bf466dea720192886e97ff5 (patch)
tree5d925028e90ffa3c408417aa070cf0458cfa6010
parent6706079a22a149d8158bd1a208c740ea4e805a20 (diff)
downloadrust_rrule-05e9450ea926833d2bf466dea720192886e97ff5.zip
Bug fix: unable to parse dtstart when it is date instead of datetime
-rw-r--r--Cargo.toml2
-rw-r--r--src/options.rs14
-rw-r--r--src/rrulestr.rs46
3 files changed, 45 insertions, 17 deletions
diff --git a/Cargo.toml b/Cargo.toml
index 17654ee..3767b93 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -2,7 +2,7 @@
name = "rrule"
description = "A pure Rust implementation of recurrence rules as defined in the iCalendar RFC."
license = "MIT"
-version = "0.3.3"
+version = "0.3.4"
documentation = "https://docs.rs/rrule"
repository = "https://github.com/fmeringdal/rust_rrule"
authors = ["Fredrik Meringdal"]
diff --git a/src/options.rs b/src/options.rs
index dc2d186..4e6f1cd 100644
--- a/src/options.rs
+++ b/src/options.rs
@@ -248,3 +248,17 @@ impl Display for RRuleParseError {
}
impl Error for RRuleParseError {}
+
+
+pub fn weekday_from_str(val: &str) -> Result<Weekday, String> {
+ match val {
+ "MO" => Ok(Weekday::Mon),
+ "TU" => Ok(Weekday::Tue),
+ "WE" => Ok(Weekday::Wed),
+ "TH" => Ok(Weekday::Thu),
+ "FR" => Ok(Weekday::Fri),
+ "SA" => Ok(Weekday::Sat),
+ "SU" => Ok(Weekday::Sun),
+ _ => Err(format!("Invalid weekday: {}", val)),
+ }
+} \ No newline at end of file
diff --git a/src/rrulestr.rs b/src/rrulestr.rs
index eb5a5be..1d263ed 100644
--- a/src/rrulestr.rs
+++ b/src/rrulestr.rs
@@ -3,6 +3,7 @@ use crate::options::*;
use crate::parse_options::parse_options;
use crate::rrule::RRule;
use crate::rruleset::RRuleSet;
+use crate::datetime::get_weekday_val;
use chrono::prelude::*;
use chrono_tz::{Tz, UTC};
use regex::Regex;
@@ -37,12 +38,13 @@ fn parse_datestring_bit<T: FromStr>(
}
fn datestring_to_date(dt: &str, tz: &Tz) -> Result<DTime, RRuleParseError> {
+
let bits = DATESTR_RE.captures(dt);
if bits.is_none() {
return Err(RRuleParseError(format!("Invalid datetime: {}", dt)));
}
let bits = bits.unwrap();
- if bits.len() < 7 {
+ if bits.len() < 3 {
return Err(RRuleParseError(format!("Invalid datetime: {}", dt)));
}
@@ -53,9 +55,9 @@ fn datestring_to_date(dt: &str, tz: &Tz) -> Result<DTime, RRuleParseError> {
parse_datestring_bit(&bits, 3, dt)?,
)
.and_hms(
- parse_datestring_bit(&bits, 5, dt)?,
- parse_datestring_bit(&bits, 6, dt)?,
- parse_datestring_bit(&bits, 7, dt)?,
+ parse_datestring_bit(&bits, 5, dt).unwrap_or(0),
+ parse_datestring_bit(&bits, 6, dt).unwrap_or(0),
+ parse_datestring_bit(&bits, 7, dt).unwrap_or(0),
));
}
@@ -69,7 +71,7 @@ fn parse_dtstart(s: &str) -> Result<Options, RRuleParseError> {
} else {
UTC
};
-
+
let dtstart_str = match caps.get(2) {
Some(dt) => dt.as_str(),
None => return Err(RRuleParseError(format!("Invalid datetime: {}", s))),
@@ -153,14 +155,14 @@ fn parse_rrule(line: &str) -> Result<Options, RRuleParseError> {
None => return Err(RRuleParseError(format!("Invalid frequenzy: {}", value))),
},
"WKST" => {
- let wkst = stringval_to_int(value, format!("Invalid weekstart value"))?;
- if wkst > 6 {
- return Err(RRuleParseError(format!(
- "Invalid wkst value: {}. It must be between 0 and 6",
- wkst
- )));
- };
- options.wkst = Some(wkst);
+ match weekday_from_str(value) {
+ Ok(weekday) => {
+ options.wkst = Some(get_weekday_val(&weekday));
+ }
+ Err(e) => {
+ return Err(RRuleParseError(e));
+ }
+ }
}
"COUNT" => {
let count = stringval_to_int(value, format!("Invalid count"))?;
@@ -501,7 +503,12 @@ fn parse_rdate(
Ok(rdatevals)
}
+fn preprocess_rrule_string(s: &str) -> String {
+ s.replace("DTSTART;VALUE=DATETIME", "DTSTART").replace("DTSTART;VALUE=DATE", "DTSTART")
+}
+
pub fn build_rruleset(s: &str) -> Result<RRuleSet, RRuleParseError> {
+ let s = preprocess_rrule_string(s);
let ParsedInput {
mut rrule_vals,
rdate_vals,
@@ -510,7 +517,7 @@ pub fn build_rruleset(s: &str) -> Result<RRuleSet, RRuleParseError> {
dtstart,
tzid,
..
- } = parse_input(s)?;
+ } = parse_input(&s)?;
let mut rset = RRuleSet::new();
rset.dtstart = dtstart;
@@ -544,12 +551,14 @@ pub fn build_rruleset(s: &str) -> Result<RRuleSet, RRuleParseError> {
}
pub fn build_rrule(s: &str) -> Result<RRule, RRuleParseError> {
+ let s = preprocess_rrule_string(s);
+
let ParsedInput {
mut rrule_vals,
tzid,
dtstart,
..
- } = parse_input(s)?;
+ } = parse_input(&s)?;
rrule_vals[0].tzid = tzid;
rrule_vals[0].dtstart = dtstart;
@@ -585,7 +594,6 @@ mod test {
#[test]
fn it_works_4() {
let res = build_rruleset("DTSTART:20120201T120000Z\nRRULE:FREQ=DAILY;COUNT=5\nEXDATE;TZID=Europe/Berlin:20120202T130000Z,20120203T130000Z");
- println!("{:?}", res);
assert!(res.is_ok());
}
@@ -663,6 +671,12 @@ mod test {
}
#[test]
+ fn parses_dtstart_when_just_date() {
+ let res = build_rruleset("DTSTART;VALUE=DATE:20200812\nRRULE:FREQ=WEEKLY;UNTIL=20210511T220000Z;INTERVAL=1;BYDAY=WE;WKST=MO");
+ assert!(res.is_ok());
+ }
+
+ #[test]
#[ignore = "Only for benching"]
fn bench() {
let now = std::time::SystemTime::now();