Skip to content

Commit

Permalink
Merge pull request #122 from WhyNotHugo/timezone
Browse files Browse the repository at this point in the history
Drop alias Datetime; use chrono::Datetime
  • Loading branch information
fmeringdal authored Jul 9, 2024
2 parents 8402921 + c83c5a0 commit 12a1c0a
Show file tree
Hide file tree
Showing 17 changed files with 112 additions and 104 deletions.
14 changes: 6 additions & 8 deletions rrule/src/core/datetime.rs
Original file line number Diff line number Diff line change
@@ -1,38 +1,36 @@
use super::timezone::Tz;
use chrono::{Datelike, Duration, NaiveTime, Timelike};

pub(crate) type DateTime = chrono::DateTime<Tz>;

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<Tz>) -> 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<Tz>) -> 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<Tz>) -> 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<Tz>) -> 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<Tz>) -> 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: <https://tools.ietf.org/html/rfc5545#section-3.3.5>
pub(crate) fn datetime_to_ical_format(dt: &DateTime) -> String {
pub(crate) fn datetime_to_ical_format(dt: &chrono::DateTime<Tz>) -> String {
let mut tz_prefix = String::new();
let mut tz_postfix = String::new();
let tz = dt.timezone();
Expand Down
2 changes: 1 addition & 1 deletion rrule/src/core/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
17 changes: 9 additions & 8 deletions rrule/src/core/rrule.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
use super::datetime::DateTime;
use crate::core::get_day;
use crate::core::get_hour;
use crate::core::get_minute;
Expand All @@ -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};
Expand Down Expand Up @@ -230,7 +231,7 @@ pub struct RRule<Stage = Validated> {
/// 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<DateTime>,
pub(crate) until: Option<DateTime<Tz>>,
/// The start day of the week.
/// This will affect recurrences based on weekly periods.
pub(crate) week_start: Weekday,
Expand Down Expand Up @@ -337,7 +338,7 @@ impl RRule<Unvalidated> {
/// 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<Tz>) -> Self {
self.until = Some(until);
self
}
Expand Down Expand Up @@ -442,7 +443,7 @@ impl RRule<Unvalidated> {
}

/// 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<Tz>) -> 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;
Expand Down Expand Up @@ -548,7 +549,7 @@ impl RRule<Unvalidated> {
/// # Errors
///
/// If the properties aren't valid, it will return [`RRuleError`].
pub fn validate(self, dt_start: DateTime) -> Result<RRule<Validated>, RRuleError> {
pub fn validate(self, dt_start: DateTime<Tz>) -> Result<RRule<Validated>, RRuleError> {
let rrule = self.finalize_parsed_rrule(&dt_start);

// Validate required checks (defined by RFC 5545)
Expand Down Expand Up @@ -603,15 +604,15 @@ impl RRule<Unvalidated> {
/// # Errors
///
/// Returns [`RRuleError::ValidationError`] in case the rrule is invalid.
pub fn build(self, dt_start: DateTime) -> Result<RRuleSet, RRuleError> {
pub fn build(self, dt_start: DateTime<Tz>) -> Result<RRuleSet, RRuleError> {
let rrule = self.validate(dt_start)?;
let rrule_set = RRuleSet::new(dt_start).rrule(rrule);
Ok(rrule_set)
}
}

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<Tz>, limited: bool) -> RRuleIter {
RRuleIter::new(self, &dt_start, limited)
}
}
Expand Down Expand Up @@ -788,7 +789,7 @@ impl<S> RRule<S> {

/// Get the until of the recurrence.
#[must_use]
pub fn get_until(&self) -> Option<&DateTime> {
pub fn get_until(&self) -> Option<&DateTime<Tz>> {
self.until.as_ref()
}

Expand Down
38 changes: 19 additions & 19 deletions rrule/src/core/rruleset.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -16,17 +16,17 @@ pub struct RRuleSet {
/// List of rrules.
pub(crate) rrule: Vec<RRule>,
/// List of rdates.
pub(crate) rdate: Vec<DateTime>,
pub(crate) rdate: Vec<DateTime<Tz>>,
/// List of exules.
pub(crate) exrule: Vec<RRule>,
/// List of exdates.
pub(crate) exdate: Vec<DateTime>,
pub(crate) exdate: Vec<DateTime<Tz>>,
/// The start datetime of the recurring event.
pub(crate) dt_start: DateTime,
pub(crate) dt_start: DateTime<Tz>,
/// If set, all returned recurrences must be before this date.
pub(crate) before: Option<DateTime>,
pub(crate) before: Option<DateTime<Tz>>,
/// If set, all returned recurrences must be after this date.
pub(crate) after: Option<DateTime>,
pub(crate) after: Option<DateTime<Tz>>,
/// If validation limits are enabled
pub(crate) limited: bool,
}
Expand All @@ -35,7 +35,7 @@ pub struct RRuleSet {
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct RRuleResult {
/// List of recurrences.
pub dates: Vec<DateTime>,
pub dates: Vec<DateTime<Tz>>,
/// It is being true if the list of dates is limited.
/// To indicate that it can potentially contain more dates.
pub limited: bool,
Expand All @@ -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<Tz>) -> Self {
Self {
dt_start,
rrule: vec![],
Expand All @@ -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<Tz>) -> Self {
self.before = Some(dt);
self
}
Expand All @@ -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<Tz>) -> Self {
self.after = Some(dt);
self
}
Expand All @@ -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<Tz>) -> 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<Tz>) -> Self {
self.exdate.push(exdate);
self
}
Expand All @@ -130,14 +130,14 @@ impl RRuleSet {

/// Sets the rdates of the set.
#[must_use]
pub fn set_rdates(mut self, rdates: Vec<DateTime>) -> Self {
pub fn set_rdates(mut self, rdates: Vec<DateTime<Tz>>) -> Self {
self.rdate = rdates;
self
}

/// Set the exdates of the set.
#[must_use]
pub fn set_exdates(mut self, exdates: Vec<DateTime>) -> Self {
pub fn set_exdates(mut self, exdates: Vec<DateTime<Tz>>) -> Self {
self.exdate = exdates;
self
}
Expand All @@ -156,19 +156,19 @@ impl RRuleSet {

/// Returns the rdates of the set.
#[must_use]
pub fn get_rdate(&self) -> &Vec<DateTime> {
pub fn get_rdate(&self) -> &Vec<DateTime<Tz>> {
&self.rdate
}

/// Returns the exdates of the set.
#[must_use]
pub fn get_exdate(&self) -> &Vec<DateTime> {
pub fn get_exdate(&self) -> &Vec<DateTime<Tz>> {
&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<Tz> {
&self.dt_start
}

Expand Down Expand Up @@ -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<DateTime> {
pub fn all_unchecked(self) -> Vec<DateTime<Tz>> {
collect_with_error(self.into_iter(), &self.after, &self.before, true, None).dates
}

Expand Down
21 changes: 12 additions & 9 deletions rrule/src/core/utils.rs
Original file line number Diff line number Diff line change
@@ -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,
Expand All @@ -12,13 +11,13 @@ use std::ops::{
/// otherwise the second value of the return tuple will be `None`.
pub(super) fn collect_with_error<T>(
mut iterator: T,
start: &Option<DateTime>,
end: &Option<DateTime>,
start: &Option<chrono::DateTime<Tz>>,
end: &Option<chrono::DateTime<Tz>>,
inclusive: bool,
limit: Option<u16>,
) -> RRuleResult
where
T: Iterator<Item = DateTime> + WasLimited,
T: Iterator<Item = chrono::DateTime<Tz>> + WasLimited,
{
let mut list = vec![];
let mut was_limited = false;
Expand Down Expand Up @@ -48,7 +47,11 @@ where
}

/// Checks if `date` is after `end`.
fn has_reached_the_end(date: &DateTime, end: &Option<DateTime>, inclusive: bool) -> bool {
fn has_reached_the_end(
date: &chrono::DateTime<Tz>,
end: &Option<chrono::DateTime<Tz>>,
inclusive: bool,
) -> bool {
if inclusive {
match end {
Some(end) => !(..=end).contains(&date),
Expand All @@ -64,9 +67,9 @@ fn has_reached_the_end(date: &DateTime, end: &Option<DateTime>, inclusive: bool)

/// Helper function to determine if a date is within a given range.
pub(super) fn is_in_range(
date: &DateTime,
start: &Option<DateTime>,
end: &Option<DateTime>,
date: &chrono::DateTime<Tz>,
start: &Option<chrono::DateTime<Tz>>,
end: &Option<chrono::DateTime<Tz>>,
inclusive: bool,
) -> bool {
// Should it include or not include the start and/or end date?
Expand Down
6 changes: 3 additions & 3 deletions rrule/src/iter/counter_date.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -305,8 +305,8 @@ impl DateTimeIter {
}
}

impl From<&DateTime> for DateTimeIter {
fn from(dt: &DateTime) -> Self {
impl From<&chrono::DateTime<Tz>> for DateTimeIter {
fn from(dt: &chrono::DateTime<Tz>) -> Self {
Self {
year: dt.year(),
month: dt.month(),
Expand Down
6 changes: 3 additions & 3 deletions rrule/src/iter/iterinfo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand All @@ -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<Tz>) -> Self {
let year = dt_start.year();
let month = get_month(dt_start);

Expand Down
4 changes: 2 additions & 2 deletions rrule/src/iter/pos_list.rs
Original file line number Diff line number Diff line change
@@ -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(
Expand All @@ -8,7 +8,7 @@ pub(crate) fn build_pos_list(
timeset: &[NaiveTime],
year_ordinal: i64,
tz: Tz,
) -> Vec<DateTime> {
) -> Vec<chrono::DateTime<Tz>> {
let mut pos_list = vec![];

if timeset.is_empty() {
Expand Down
Loading

0 comments on commit 12a1c0a

Please sign in to comment.