From c83c5a07cfc890946e69a6442f5e1ce49f38ffd7 Mon Sep 17 00:00:00 2001 From: Hugo Osvaldo Barrera Date: Mon, 8 Jul 2024 17:58:24 +0200 Subject: [PATCH] Drop alias Datetime; use chrono::Datetime This is mostly in preparation for https://github.com/fmeringdal/rust-rrule/issues/24 A lot of these functions will continue taking a `DateTime` as parameter, but other will allow a generic `Timezone` as parameter. --- rrule/src/core/datetime.rs | 14 +++---- rrule/src/core/mod.rs | 2 +- rrule/src/core/rrule.rs | 17 +++++---- rrule/src/core/rruleset.rs | 38 +++++++++---------- rrule/src/core/utils.rs | 21 +++++----- rrule/src/iter/counter_date.rs | 6 +-- rrule/src/iter/iterinfo.rs | 6 +-- rrule/src/iter/pos_list.rs | 4 +- rrule/src/iter/rrule_iter.rs | 18 ++++----- rrule/src/iter/rruleset_iter.rs | 24 ++++++------ rrule/src/iter/utils.rs | 8 +++- .../parser/content_line/date_content_line.rs | 4 +- rrule/src/parser/content_line/mod.rs | 6 +-- .../content_line/start_date_content_line.rs | 4 +- rrule/src/parser/datetime.rs | 7 +--- rrule/src/tests/common.rs | 2 +- rrule/src/validator/validate_rrule.rs | 35 +++++++++-------- 17 files changed, 112 insertions(+), 104 deletions(-) diff --git a/rrule/src/core/datetime.rs b/rrule/src/core/datetime.rs index 23b9ab8..330ec89 100644 --- a/rrule/src/core/datetime.rs +++ b/rrule/src/core/datetime.rs @@ -1,38 +1,36 @@ use super::timezone::Tz; use chrono::{Datelike, Duration, NaiveTime, Timelike}; -pub(crate) type DateTime = chrono::DateTime; - pub(crate) fn duration_from_midnight(time: NaiveTime) -> Duration { Duration::hours(i64::from(time.hour())) + Duration::minutes(i64::from(time.minute())) + Duration::seconds(i64::from(time.second())) } -pub(crate) fn get_month(dt: &DateTime) -> u8 { +pub(crate) fn get_month(dt: &chrono::DateTime) -> u8 { u8::try_from(dt.month()).expect("month is between 1-12 which is covered by u8") } -pub(crate) fn get_day(dt: &DateTime) -> i8 { +pub(crate) fn get_day(dt: &chrono::DateTime) -> i8 { i8::try_from(dt.day()).expect("day is between 1-31 which is covered by i8") } -pub(crate) fn get_hour(dt: &DateTime) -> u8 { +pub(crate) fn get_hour(dt: &chrono::DateTime) -> u8 { u8::try_from(dt.hour()).expect("hour is between 0-23 which is covered by u8") } -pub(crate) fn get_minute(dt: &DateTime) -> u8 { +pub(crate) fn get_minute(dt: &chrono::DateTime) -> u8 { u8::try_from(dt.minute()).expect("minute is between 0-59 which is covered by u8") } -pub(crate) fn get_second(dt: &DateTime) -> u8 { +pub(crate) fn get_second(dt: &chrono::DateTime) -> u8 { u8::try_from(dt.second()).expect("second is between 0-59 which is covered by u8") } /// Generates an iCalendar date-time string format with the prefix symbols. /// Like: `:19970714T173000Z` or `;TZID=America/New_York:19970714T133000` /// ref: -pub(crate) fn datetime_to_ical_format(dt: &DateTime) -> String { +pub(crate) fn datetime_to_ical_format(dt: &chrono::DateTime) -> String { let mut tz_prefix = String::new(); let mut tz_postfix = String::new(); let tz = dt.timezone(); diff --git a/rrule/src/core/mod.rs b/rrule/src/core/mod.rs index aff23ce..a7e17ac 100644 --- a/rrule/src/core/mod.rs +++ b/rrule/src/core/mod.rs @@ -8,7 +8,7 @@ pub(crate) mod utils; pub use self::rrule::{Frequency, NWeekday, RRule}; pub use self::rruleset::{RRuleResult, RRuleSet}; pub(crate) use datetime::{ - duration_from_midnight, get_day, get_hour, get_minute, get_month, get_second, DateTime, + duration_from_midnight, get_day, get_hour, get_minute, get_month, get_second, }; pub use timezone::Tz; diff --git a/rrule/src/core/rrule.rs b/rrule/src/core/rrule.rs index 3ea9838..aed66ea 100644 --- a/rrule/src/core/rrule.rs +++ b/rrule/src/core/rrule.rs @@ -1,4 +1,3 @@ -use super::datetime::DateTime; use crate::core::get_day; use crate::core::get_hour; use crate::core::get_minute; @@ -10,7 +9,9 @@ use crate::parser::ContentLineCaptures; use crate::parser::ParseError; use crate::validator::validate_rrule; use crate::validator::ValidationError; +use crate::Tz; use crate::{RRuleError, RRuleSet, Unvalidated, Validated}; +use chrono::DateTime; use chrono::{Datelike, Month, Weekday}; #[cfg(feature = "serde")] use serde_with::{serde_as, DeserializeFromStr, SerializeDisplay}; @@ -230,7 +231,7 @@ pub struct RRule { /// The end date after which new events will no longer be generated. /// If the `DateTime` is equal to an instance of the event, it will be the last event. #[cfg_attr(feature = "serde", serde_as(as = "DisplayFromStr"))] - pub(crate) until: Option, + pub(crate) until: Option>, /// The start day of the week. /// This will affect recurrences based on weekly periods. pub(crate) week_start: Weekday, @@ -337,7 +338,7 @@ impl RRule { /// If given, this must be a datetime instance specifying the /// upper-bound limit of the recurrence. #[must_use] - pub fn until(mut self, until: DateTime) -> Self { + pub fn until(mut self, until: DateTime) -> Self { self.until = Some(until); self } @@ -442,7 +443,7 @@ impl RRule { } /// Fills in some additional fields in order to make iter work correctly. - pub(crate) fn finalize_parsed_rrule(mut self, dt_start: &DateTime) -> Self { + pub(crate) fn finalize_parsed_rrule(mut self, dt_start: &DateTime) -> Self { // TEMP: move negative months to another list let mut by_month_day = vec![]; let mut by_n_month_day = self.by_n_month_day; @@ -548,7 +549,7 @@ impl RRule { /// # Errors /// /// If the properties aren't valid, it will return [`RRuleError`]. - pub fn validate(self, dt_start: DateTime) -> Result, RRuleError> { + pub fn validate(self, dt_start: DateTime) -> Result, RRuleError> { let rrule = self.finalize_parsed_rrule(&dt_start); // Validate required checks (defined by RFC 5545) @@ -603,7 +604,7 @@ impl RRule { /// # Errors /// /// Returns [`RRuleError::ValidationError`] in case the rrule is invalid. - pub fn build(self, dt_start: DateTime) -> Result { + pub fn build(self, dt_start: DateTime) -> Result { let rrule = self.validate(dt_start)?; let rrule_set = RRuleSet::new(dt_start).rrule(rrule); Ok(rrule_set) @@ -611,7 +612,7 @@ impl RRule { } impl RRule { - pub(crate) fn iter_with_ctx(&self, dt_start: DateTime, limited: bool) -> RRuleIter { + pub(crate) fn iter_with_ctx(&self, dt_start: DateTime, limited: bool) -> RRuleIter { RRuleIter::new(self, &dt_start, limited) } } @@ -788,7 +789,7 @@ impl RRule { /// Get the until of the recurrence. #[must_use] - pub fn get_until(&self) -> Option<&DateTime> { + pub fn get_until(&self) -> Option<&DateTime> { self.until.as_ref() } diff --git a/rrule/src/core/rruleset.rs b/rrule/src/core/rruleset.rs index c85b39a..be6f3e3 100644 --- a/rrule/src/core/rruleset.rs +++ b/rrule/src/core/rruleset.rs @@ -1,8 +1,8 @@ use crate::core::datetime::datetime_to_ical_format; use crate::core::utils::collect_with_error; -use crate::core::DateTime; use crate::parser::{ContentLine, Grammar}; -use crate::{ParseError, RRule, RRuleError}; +use crate::{ParseError, RRule, RRuleError, Tz}; +use chrono::DateTime; #[cfg(feature = "serde")] use serde_with::{serde_as, DeserializeFromStr, SerializeDisplay}; use std::fmt::Display; @@ -16,17 +16,17 @@ pub struct RRuleSet { /// List of rrules. pub(crate) rrule: Vec, /// List of rdates. - pub(crate) rdate: Vec, + pub(crate) rdate: Vec>, /// List of exules. pub(crate) exrule: Vec, /// List of exdates. - pub(crate) exdate: Vec, + pub(crate) exdate: Vec>, /// The start datetime of the recurring event. - pub(crate) dt_start: DateTime, + pub(crate) dt_start: DateTime, /// If set, all returned recurrences must be before this date. - pub(crate) before: Option, + pub(crate) before: Option>, /// If set, all returned recurrences must be after this date. - pub(crate) after: Option, + pub(crate) after: Option>, /// If validation limits are enabled pub(crate) limited: bool, } @@ -35,7 +35,7 @@ pub struct RRuleSet { #[derive(Clone, Debug, PartialEq, Eq)] pub struct RRuleResult { /// List of recurrences. - pub dates: Vec, + pub dates: Vec>, /// It is being true if the list of dates is limited. /// To indicate that it can potentially contain more dates. pub limited: bool, @@ -44,7 +44,7 @@ pub struct RRuleResult { impl RRuleSet { /// Creates an empty [`RRuleSet`], starting from `ds_start`. #[must_use] - pub fn new(dt_start: DateTime) -> Self { + pub fn new(dt_start: DateTime) -> Self { Self { dt_start, rrule: vec![], @@ -70,7 +70,7 @@ impl RRuleSet { /// /// This value will not be used if you use the `Iterator` API directly. #[must_use] - pub fn before(mut self, dt: DateTime) -> Self { + pub fn before(mut self, dt: DateTime) -> Self { self.before = Some(dt); self } @@ -79,7 +79,7 @@ impl RRuleSet { /// /// This value will not be used if you use the `Iterator` API directly. #[must_use] - pub fn after(mut self, dt: DateTime) -> Self { + pub fn after(mut self, dt: DateTime) -> Self { self.after = Some(dt); self } @@ -101,14 +101,14 @@ impl RRuleSet { /// Adds a new rdate to the set. #[must_use] - pub fn rdate(mut self, rdate: DateTime) -> Self { + pub fn rdate(mut self, rdate: DateTime) -> Self { self.rdate.push(rdate); self } /// Adds a new exdate to the set. #[must_use] - pub fn exdate(mut self, exdate: DateTime) -> Self { + pub fn exdate(mut self, exdate: DateTime) -> Self { self.exdate.push(exdate); self } @@ -130,14 +130,14 @@ impl RRuleSet { /// Sets the rdates of the set. #[must_use] - pub fn set_rdates(mut self, rdates: Vec) -> Self { + pub fn set_rdates(mut self, rdates: Vec>) -> Self { self.rdate = rdates; self } /// Set the exdates of the set. #[must_use] - pub fn set_exdates(mut self, exdates: Vec) -> Self { + pub fn set_exdates(mut self, exdates: Vec>) -> Self { self.exdate = exdates; self } @@ -156,19 +156,19 @@ impl RRuleSet { /// Returns the rdates of the set. #[must_use] - pub fn get_rdate(&self) -> &Vec { + pub fn get_rdate(&self) -> &Vec> { &self.rdate } /// Returns the exdates of the set. #[must_use] - pub fn get_exdate(&self) -> &Vec { + pub fn get_exdate(&self) -> &Vec> { &self.exdate } /// Returns the start datetime of the recurring event. #[must_use] - pub fn get_dt_start(&self) -> &DateTime { + pub fn get_dt_start(&self) -> &DateTime { &self.dt_start } @@ -208,7 +208,7 @@ impl RRuleSet { /// This method does not enforce any validation limits and might lead to /// very long iteration times. Please read the `SECURITY.md` for more information. #[must_use] - pub fn all_unchecked(self) -> Vec { + pub fn all_unchecked(self) -> Vec> { collect_with_error(self.into_iter(), &self.after, &self.before, true, None).dates } diff --git a/rrule/src/core/utils.rs b/rrule/src/core/utils.rs index 15ed87d..d593af7 100644 --- a/rrule/src/core/utils.rs +++ b/rrule/src/core/utils.rs @@ -1,6 +1,5 @@ -use super::DateTime; -use crate::iter::rrule_iter::WasLimited; use crate::RRuleResult; +use crate::{iter::rrule_iter::WasLimited, Tz}; use std::ops::{ Bound::{Excluded, Unbounded}, RangeBounds, @@ -12,13 +11,13 @@ use std::ops::{ /// otherwise the second value of the return tuple will be `None`. pub(super) fn collect_with_error( mut iterator: T, - start: &Option, - end: &Option, + start: &Option>, + end: &Option>, inclusive: bool, limit: Option, ) -> RRuleResult where - T: Iterator + WasLimited, + T: Iterator> + WasLimited, { let mut list = vec![]; let mut was_limited = false; @@ -48,7 +47,11 @@ where } /// Checks if `date` is after `end`. -fn has_reached_the_end(date: &DateTime, end: &Option, inclusive: bool) -> bool { +fn has_reached_the_end( + date: &chrono::DateTime, + end: &Option>, + inclusive: bool, +) -> bool { if inclusive { match end { Some(end) => !(..=end).contains(&date), @@ -64,9 +67,9 @@ fn has_reached_the_end(date: &DateTime, end: &Option, inclusive: bool) /// Helper function to determine if a date is within a given range. pub(super) fn is_in_range( - date: &DateTime, - start: &Option, - end: &Option, + date: &chrono::DateTime, + start: &Option>, + end: &Option>, inclusive: bool, ) -> bool { // Should it include or not include the start and/or end date? diff --git a/rrule/src/iter/counter_date.rs b/rrule/src/iter/counter_date.rs index 621fce3..3f14746 100644 --- a/rrule/src/iter/counter_date.rs +++ b/rrule/src/iter/counter_date.rs @@ -2,7 +2,7 @@ use std::collections::HashSet; use chrono::{Datelike, TimeZone, Timelike, Utc, Weekday}; -use crate::{core::DateTime, Frequency, RRule, RRuleError}; +use crate::{Frequency, RRule, RRuleError, Tz}; use super::{ checks, @@ -305,8 +305,8 @@ impl DateTimeIter { } } -impl From<&DateTime> for DateTimeIter { - fn from(dt: &DateTime) -> Self { +impl From<&chrono::DateTime> for DateTimeIter { + fn from(dt: &chrono::DateTime) -> Self { Self { year: dt.year(), month: dt.month(), diff --git a/rrule/src/iter/iterinfo.rs b/rrule/src/iter/iterinfo.rs index 1110e38..eb5e2ec 100644 --- a/rrule/src/iter/iterinfo.rs +++ b/rrule/src/iter/iterinfo.rs @@ -2,8 +2,8 @@ use super::counter_date::DateTimeIter; #[cfg(feature = "by-easter")] use super::easter::easter; use super::{monthinfo::MonthInfo, yearinfo::YearInfo}; -use crate::core::{get_month, DateTime}; -use crate::{Frequency, NWeekday, RRule}; +use crate::core::get_month; +use crate::{Frequency, NWeekday, RRule, Tz}; use chrono::{Datelike, NaiveTime, TimeZone}; #[derive(Debug, Clone)] @@ -15,7 +15,7 @@ pub(crate) struct IterInfo { } impl IterInfo { - pub fn new(rrule: &RRule, dt_start: &DateTime) -> Self { + pub fn new(rrule: &RRule, dt_start: &chrono::DateTime) -> Self { let year = dt_start.year(); let month = get_month(dt_start); diff --git a/rrule/src/iter/pos_list.rs b/rrule/src/iter/pos_list.rs index da98d9c..1d20012 100644 --- a/rrule/src/iter/pos_list.rs +++ b/rrule/src/iter/pos_list.rs @@ -1,5 +1,5 @@ use super::utils::{add_time_to_date, date_from_ordinal, pymod}; -use crate::core::{DateTime, Tz}; +use crate::core::Tz; use chrono::NaiveTime; pub(crate) fn build_pos_list( @@ -8,7 +8,7 @@ pub(crate) fn build_pos_list( timeset: &[NaiveTime], year_ordinal: i64, tz: Tz, -) -> Vec { +) -> Vec> { let mut pos_list = vec![]; if timeset.is_empty() { diff --git a/rrule/src/iter/rrule_iter.rs b/rrule/src/iter/rrule_iter.rs index e317ce0..2fb7c93 100644 --- a/rrule/src/iter/rrule_iter.rs +++ b/rrule/src/iter/rrule_iter.rs @@ -2,7 +2,7 @@ use super::counter_date::DateTimeIter; use super::utils::add_time_to_date; use super::{build_pos_list, utils::date_from_ordinal, IterInfo, MAX_ITER_LOOP}; use crate::core::{get_hour, get_minute, get_second}; -use crate::{core::DateTime, Frequency, RRule}; +use crate::{Frequency, RRule, Tz}; use chrono::NaiveTime; use std::collections::VecDeque; @@ -12,9 +12,9 @@ pub(crate) struct RRuleIter { pub(crate) counter_date: DateTimeIter, pub(crate) ii: IterInfo, pub(crate) timeset: Vec, - pub(crate) dt_start: DateTime, + pub(crate) dt_start: chrono::DateTime, /// Buffer of datetimes is not yet yielded - pub(crate) buffer: VecDeque, + pub(crate) buffer: VecDeque>, /// Indicate of iterator should not return more items. /// Once set `true` is will always return `None`. pub(crate) finished: bool, @@ -28,7 +28,7 @@ pub(crate) struct RRuleIter { } impl RRuleIter { - pub(crate) fn new(rrule: &RRule, dt_start: &DateTime, limited: bool) -> Self { + pub(crate) fn new(rrule: &RRule, dt_start: &chrono::DateTime, limited: bool) -> Self { let ii = IterInfo::new(rrule, dt_start); let hour = get_hour(dt_start); @@ -37,7 +37,7 @@ impl RRuleIter { let timeset = ii.get_timeset(hour, minute, second); let count = ii.rrule().count; - RRuleIter { + Self { counter_date: dt_start.into(), ii, timeset, @@ -53,11 +53,11 @@ impl RRuleIter { /// Attempts to add a date to the result. Returns `true` if we should /// terminate the iteration. fn try_add_datetime( - dt: DateTime, + dt: chrono::DateTime, rrule: &RRule, count: &mut Option, - buffer: &mut VecDeque, - dt_start: &DateTime, + buffer: &mut VecDeque>, + dt_start: &chrono::DateTime, ) -> bool { if matches!(rrule.until, Some(until) if dt > until) { // We can break because `pos_list` is sorted and @@ -199,7 +199,7 @@ impl RRuleIter { } impl Iterator for RRuleIter { - type Item = DateTime; + type Item = chrono::DateTime; fn next(&mut self) -> Option { if !self.buffer.is_empty() { diff --git a/rrule/src/iter/rruleset_iter.rs b/rrule/src/iter/rruleset_iter.rs index 3178f62..78f69e5 100644 --- a/rrule/src/iter/rruleset_iter.rs +++ b/rrule/src/iter/rruleset_iter.rs @@ -1,7 +1,9 @@ +use chrono::DateTime; + use super::rrule_iter::WasLimited; use super::{rrule_iter::RRuleIter, MAX_ITER_LOOP}; -use crate::RRuleError; -use crate::{core::DateTime, RRuleSet}; +use crate::RRuleSet; +use crate::{RRuleError, Tz}; use std::collections::BTreeSet; use std::str::FromStr; use std::{collections::HashMap, iter::Iterator}; @@ -9,23 +11,23 @@ use std::{collections::HashMap, iter::Iterator}; #[derive(Debug, Clone)] /// Iterator over all the dates in an [`RRuleSet`]. pub struct RRuleSetIter { - queue: HashMap, + queue: HashMap>, limited: bool, rrule_iters: Vec, exrules: Vec, exdates: BTreeSet, /// Sorted additional dates in descending order - rdates: Vec, + rdates: Vec>, was_limited: bool, } impl RRuleSetIter { fn generate_date( - dates: &mut Vec, + dates: &mut Vec>, exrules: &mut [RRuleIter], exdates: &mut BTreeSet, limited: bool, - ) -> (Option, bool) { + ) -> (Option>, bool) { if dates.is_empty() { return (None, false); } @@ -59,7 +61,7 @@ impl RRuleSetIter { exrules: &mut [RRuleIter], exdates: &mut BTreeSet, limited: bool, - ) -> (Option, bool) { + ) -> (Option>, bool) { let mut date = match rrule_iter.next() { Some(d) => d, None => return (None, false), @@ -89,7 +91,7 @@ impl RRuleSetIter { } fn is_date_excluded( - date: &DateTime, + date: &DateTime, exrules: &mut [RRuleIter], exdates: &mut BTreeSet, ) -> bool { @@ -107,10 +109,10 @@ impl RRuleSetIter { } impl Iterator for RRuleSetIter { - type Item = DateTime; + type Item = DateTime; fn next(&mut self) -> Option { - let mut next_date: Option<(usize, DateTime)> = None; + let mut next_date: Option<(usize, DateTime)> = None; // If there already was an error, return the error again. if self.was_limited { @@ -194,7 +196,7 @@ impl Iterator for RRuleSetIter { } impl IntoIterator for &RRuleSet { - type Item = DateTime; + type Item = DateTime; type IntoIter = RRuleSetIter; diff --git a/rrule/src/iter/utils.rs b/rrule/src/iter/utils.rs index daeceb1..f587af1 100644 --- a/rrule/src/iter/utils.rs +++ b/rrule/src/iter/utils.rs @@ -1,6 +1,6 @@ use std::ops; -use crate::core::{duration_from_midnight, DateTime, Tz}; +use crate::core::{duration_from_midnight, Tz}; use chrono::{NaiveDate, NaiveTime, Utc}; const DAY_SECS: i64 = 24 * 60 * 60; @@ -72,7 +72,11 @@ where } } -pub(crate) fn add_time_to_date(tz: Tz, date: NaiveDate, time: NaiveTime) -> Option { +pub(crate) fn add_time_to_date( + tz: Tz, + date: NaiveDate, + time: NaiveTime, +) -> Option> { if let Some(dt) = date.and_time(time).and_local_timezone(tz).single() { return Some(dt); } diff --git a/rrule/src/parser/content_line/date_content_line.rs b/rrule/src/parser/content_line/date_content_line.rs index 4495ec7..6cb401e 100644 --- a/rrule/src/parser/content_line/date_content_line.rs +++ b/rrule/src/parser/content_line/date_content_line.rs @@ -3,11 +3,11 @@ use std::{collections::HashMap, str::FromStr}; use log::warn; use crate::{ - core::DateTime, parser::{ datetime::{datestring_to_date, parse_timezone}, ParseError, }, + Tz, }; use super::{content_line_parts::ContentLineCaptures, parameters::parse_parameters}; @@ -31,7 +31,7 @@ impl FromStr for DateParameter { } } -impl<'a> TryFrom> for Vec { +impl<'a> TryFrom> for Vec> { type Error = ParseError; fn try_from(value: ContentLineCaptures) -> Result { diff --git a/rrule/src/parser/content_line/mod.rs b/rrule/src/parser/content_line/mod.rs index 703fc05..b005560 100644 --- a/rrule/src/parser/content_line/mod.rs +++ b/rrule/src/parser/content_line/mod.rs @@ -7,8 +7,8 @@ mod start_date_content_line; use std::fmt::Display; use std::str::FromStr; -use crate::core::DateTime; use crate::RRule; +use crate::Tz; use crate::Unvalidated; pub(crate) use content_line_parts::ContentLineCaptures; @@ -20,8 +20,8 @@ use super::ParseError; pub(crate) enum ContentLine { RRule(RRule), ExRule(RRule), - ExDate(Vec), - RDate(Vec), + ExDate(Vec>), + RDate(Vec>), } #[derive(Debug, PartialEq, Clone, Copy)] diff --git a/rrule/src/parser/content_line/start_date_content_line.rs b/rrule/src/parser/content_line/start_date_content_line.rs index 6c96793..fdc32c3 100644 --- a/rrule/src/parser/content_line/start_date_content_line.rs +++ b/rrule/src/parser/content_line/start_date_content_line.rs @@ -5,7 +5,7 @@ use super::{ parameters::parse_parameters, }; use crate::{ - core::{DateTime, Tz}, + core::Tz, parser::{ datetime::{datestring_to_date, parse_timezone}, ParseError, @@ -16,7 +16,7 @@ const UTC: Tz = Tz::UTC; #[derive(Debug, PartialEq)] pub(crate) struct StartDateContentLine { - pub datetime: DateTime, + pub datetime: chrono::DateTime, pub timezone: Option, pub value: &'static str, } diff --git a/rrule/src/parser/datetime.rs b/rrule/src/parser/datetime.rs index e3060a0..8ebbb9a 100644 --- a/rrule/src/parser/datetime.rs +++ b/rrule/src/parser/datetime.rs @@ -1,10 +1,7 @@ use std::str::FromStr; use super::{regex::ParsedDateString, ParseError}; -use crate::{ - core::{DateTime, Tz}, - NWeekday, -}; +use crate::{core::Tz, NWeekday}; use chrono::{NaiveDate, TimeZone, Weekday}; /// Attempts to convert a `str` to a `chrono_tz::Tz`. @@ -21,7 +18,7 @@ pub(crate) fn datestring_to_date( dt: &str, tz: Option, property: &str, -) -> Result { +) -> Result, ParseError> { let ParsedDateString { year, month, diff --git a/rrule/src/tests/common.rs b/rrule/src/tests/common.rs index 2ab303f..5f4c5b6 100644 --- a/rrule/src/tests/common.rs +++ b/rrule/src/tests/common.rs @@ -78,7 +78,7 @@ pub fn check_occurrences + Debug>(occurrences: &[DateTime], ex ); assert_eq!(occurrences.len(), expected.len(), "List sizes don't match"); for (given, expected) in occurrences.iter().zip(expected.iter()) { - let exp_datetime = chrono::DateTime::parse_from_rfc3339(expected.as_ref()).unwrap(); + let exp_datetime = DateTime::parse_from_rfc3339(expected.as_ref()).unwrap(); // Compare items and check if in the same offset/timezone assert_eq!( given.to_rfc3339(), diff --git a/rrule/src/validator/validate_rrule.rs b/rrule/src/validator/validate_rrule.rs index 2a5e93d..49978a8 100644 --- a/rrule/src/validator/validate_rrule.rs +++ b/rrule/src/validator/validate_rrule.rs @@ -1,6 +1,5 @@ use std::ops::RangeInclusive; -use crate::core::DateTime; use crate::{Frequency, NWeekday, RRule, Tz, Unvalidated}; use super::ValidationError; @@ -13,7 +12,8 @@ pub(crate) static MONTH_RANGE: RangeInclusive = 1..=12; /// Range: `-10_000..=10_000` pub(crate) static YEAR_RANGE: RangeInclusive = -10_000..=10_000; -type Validator = &'static dyn Fn(&RRule, &DateTime) -> Result<(), ValidationError>; +type Validator = + &'static dyn Fn(&RRule, &chrono::DateTime) -> Result<(), ValidationError>; const VALIDATION_PIPELINE: [Validator; 11] = [ &validate_until, @@ -37,7 +37,7 @@ const VALIDATION_PIPELINE: [Validator; 11] = [ /// Validation will always be enforced and can not be disabled using feature flags. pub(crate) fn validate_rrule_forced( rrule: &RRule, - dt_start: &DateTime, + dt_start: &chrono::DateTime, ) -> Result<(), ValidationError> { VALIDATION_PIPELINE .into_iter() @@ -47,7 +47,10 @@ pub(crate) fn validate_rrule_forced( // Until: // - Timezones are correctly synced as specified in the RFC // - Value should be later than `dt_start`. -fn validate_until(rrule: &RRule, dt_start: &DateTime) -> Result<(), ValidationError> { +fn validate_until( + rrule: &RRule, + dt_start: &chrono::DateTime, +) -> Result<(), ValidationError> { match rrule.until { Some(until) => { match dt_start.timezone() { @@ -91,7 +94,7 @@ fn validate_until(rrule: &RRule, dt_start: &DateTime) -> Result<(), // - Can be a value from -366 to -1 and 1 to 366 depending on `freq` fn validate_by_set_pos( rrule: &RRule, - _dt_start: &DateTime, + _dt_start: &chrono::DateTime, ) -> Result<(), ValidationError> { validate_not_equal_for_vec(&0, &rrule.by_set_pos, "BYSETPOS")?; let range = match rrule.freq { @@ -131,7 +134,7 @@ fn validate_by_set_pos( // - Can be a value from 1 to 12. fn validate_by_month( rrule: &RRule, - _dt_start: &DateTime, + _dt_start: &chrono::DateTime, ) -> Result<(), ValidationError> { validate_range_for_vec(&MONTH_RANGE, &rrule.by_month, "BYMONTH") } @@ -140,7 +143,7 @@ fn validate_by_month( // - Can be a value from -31 to -1 and 1 to 31. fn validate_by_month_day( rrule: &RRule, - _dt_start: &DateTime, + _dt_start: &chrono::DateTime, ) -> Result<(), ValidationError> { validate_not_equal_for_vec(&0, &rrule.by_month_day, "BYMONTHDAY")?; validate_range_for_vec(&(-31..=31), &rrule.by_month_day, "BYMONTHDAY")?; @@ -162,7 +165,7 @@ fn validate_by_month_day( // - Can be a value from -366 to -1 and 1 to 366. fn validate_by_year_day( rrule: &RRule, - _dt_start: &DateTime, + _dt_start: &chrono::DateTime, ) -> Result<(), ValidationError> { validate_not_equal_for_vec(&0, &rrule.by_year_day, "BYYEARDAY")?; validate_range_for_vec(&(-366..=366), &rrule.by_year_day, "BYYEARDAY")?; @@ -186,7 +189,7 @@ fn validate_by_year_day( // - Can be a value from -53 to -1 and 1 to 53. fn validate_by_week_number( rrule: &RRule, - _dt_start: &DateTime, + _dt_start: &chrono::DateTime, ) -> Result<(), ValidationError> { validate_not_equal_for_vec(&0, &rrule.by_week_no, "BYWEEKNO")?; validate_range_for_vec(&(-53..=53), &rrule.by_week_no, "BYWEEKNO")?; @@ -209,7 +212,7 @@ fn validate_by_week_number( // The Range depends on frequency and can only happen weekly, so `/7` from normal count. fn validate_by_weekday( rrule: &RRule, - _dt_start: &DateTime, + _dt_start: &chrono::DateTime, ) -> Result<(), ValidationError> { let range = match rrule.freq { Frequency::Yearly | Frequency::Daily => (-366 / 7)..=(366 / 7 + 1), // TODO is the daily range correct? @@ -239,7 +242,7 @@ fn validate_by_weekday( // - Can be a value from 0 to 23. fn validate_by_hour( rrule: &RRule, - _dt_start: &DateTime, + _dt_start: &chrono::DateTime, ) -> Result<(), ValidationError> { validate_range_for_vec(&(0..=23), &rrule.by_hour, "BYHOUR") } @@ -248,7 +251,7 @@ fn validate_by_hour( // - Can be a value from 0 to 59. fn validate_by_minute( rrule: &RRule, - _dt_start: &DateTime, + _dt_start: &chrono::DateTime, ) -> Result<(), ValidationError> { validate_range_for_vec(&(0..=59), &rrule.by_minute, "BYMINUTE") } @@ -257,14 +260,14 @@ fn validate_by_minute( // - Can be a value from 0 to 59. fn validate_by_second( rrule: &RRule, - _dt_start: &DateTime, + _dt_start: &chrono::DateTime, ) -> Result<(), ValidationError> { validate_range_for_vec(&(0..=59), &rrule.by_second, "BYSECOND") } fn validate_by_easter( rrule: &RRule, - _dt_start: &DateTime, + _dt_start: &chrono::DateTime, ) -> Result<(), ValidationError> { #[cfg(feature = "by-easter")] { @@ -590,7 +593,7 @@ mod tests { #[test] fn allows_until_with_compatible_timezone() { - fn t(start_tz: Tz, until_tz: Tz) -> (DateTime, DateTime) { + fn t(start_tz: Tz, until_tz: Tz) -> (chrono::DateTime, chrono::DateTime) { ( start_tz.with_ymd_and_hms(2020, 1, 1, 0, 0, 0).unwrap(), until_tz.with_ymd_and_hms(2020, 1, 1, 0, 0, 0).unwrap(), @@ -611,7 +614,7 @@ mod tests { #[test] fn rejects_until_with_incompatible_timezone() { - fn t(start_tz: Tz, until_tz: Tz) -> (DateTime, DateTime) { + fn t(start_tz: Tz, until_tz: Tz) -> (chrono::DateTime, chrono::DateTime) { ( start_tz.with_ymd_and_hms(2020, 1, 1, 0, 0, 0).unwrap(), until_tz.with_ymd_and_hms(2020, 1, 1, 0, 0, 0).unwrap(),