Skip to main content

rfc5545_types/
time.rs

1//! Basic time types.
2
3use calendar_types::{
4    duration::{Duration, SignedDuration},
5    primitive::Sign,
6    time::{Date, DateTime, Hour, Minute, NonLeapSecond, Utc},
7};
8
9pub use calendar_types::time::TimeFormat;
10
11/// Either a full datetime or a date-only value.
12#[derive(Debug, Clone, Copy, PartialEq, Eq)]
13pub enum DateTimeOrDate<M = TimeFormat> {
14    /// A full datetime value.
15    DateTime(DateTime<M>),
16    /// A date-only value.
17    Date(Date),
18}
19
20impl<M> DateTimeOrDate<M> {
21    /// Returns `true` if this is a date-only value.
22    pub fn is_date(&self) -> bool {
23        matches!(self, Self::Date(_))
24    }
25
26    /// Returns `true` if this is a full datetime value.
27    pub fn is_date_time(&self) -> bool {
28        matches!(self, Self::DateTime(_))
29    }
30
31    /// Converts the marker type of the inner datetime.
32    pub fn map_marker<N>(self, f: impl FnOnce(M) -> N) -> DateTimeOrDate<N> {
33        match self {
34            Self::DateTime(dt) => DateTimeOrDate::DateTime(DateTime {
35                date: dt.date,
36                time: dt.time,
37                marker: f(dt.marker),
38            }),
39            Self::Date(d) => DateTimeOrDate::Date(d),
40        }
41    }
42}
43
44/// An offset from UTC to some local time (RFC 5545 §3.3.14).
45#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
46pub struct UtcOffset {
47    /// The sign of the offset (positive = east of UTC).
48    pub sign: Sign,
49    /// The hour component of the offset.
50    pub hour: Hour,
51    /// The minute component of the offset.
52    pub minute: Minute,
53    /// The second component of the offset.
54    pub second: NonLeapSecond,
55}
56
57impl std::fmt::Display for UtcOffset {
58    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
59        write!(
60            f,
61            "{}{:02}:{:02}",
62            self.sign.as_char(),
63            self.hour as u8,
64            self.minute as u8
65        )?;
66        let sec = self.second as u8;
67        if sec != 0 {
68            write!(f, ":{sec:02}")?;
69        }
70        Ok(())
71    }
72}
73
74// ============================================================================
75// Period
76// ============================================================================
77
78/// A period of time (RFC 5545 §3.3.9).
79#[derive(Debug, Clone, Copy, PartialEq, Eq)]
80pub enum Period<M = TimeFormat> {
81    /// A period defined by explicit start and end datetimes.
82    Explicit {
83        /// The start of the period.
84        start: DateTime<M>,
85        /// The end of the period.
86        end: DateTime<M>,
87    },
88    /// A period defined by a start datetime and a duration.
89    Start {
90        /// The start of the period.
91        start: DateTime<M>,
92        /// The duration of the period.
93        duration: Duration,
94    },
95}
96
97// ============================================================================
98// RDate / ExDate sequences
99// ============================================================================
100
101/// A single RDATE value (RFC 5545 §3.8.5.2).
102#[derive(Debug, Clone, Copy, PartialEq, Eq)]
103pub enum RDate<M = TimeFormat> {
104    DateTime(DateTime<M>),
105    Date(Date),
106    Period(Period<M>),
107}
108
109/// A homogeneous sequence of RDATE values.
110#[derive(Debug, Clone, PartialEq, Eq)]
111pub enum RDateSeq<M = TimeFormat> {
112    DateTime(Vec<DateTime<M>>),
113    Date(Vec<Date>),
114    Period(Vec<Period<M>>),
115}
116
117/// A homogeneous sequence of EXDATE values.
118#[derive(Debug, Clone, PartialEq, Eq)]
119pub enum ExDateSeq<M = TimeFormat> {
120    DateTime(Vec<DateTime<M>>),
121    Date(Vec<Date>),
122}
123
124// ============================================================================
125// TriggerValue
126// ============================================================================
127
128/// The value of a TRIGGER property (RFC 5545 §3.8.6.3).
129#[derive(Debug, Clone, Copy, PartialEq, Eq)]
130pub enum TriggerValue {
131    /// A duration offset relative to the event start or end.
132    Duration(SignedDuration),
133    /// An absolute UTC datetime.
134    DateTime(DateTime<Utc>),
135}