cookie/expiration.rs
1use time::OffsetDateTime;
2
3/// A cookie's expiration: either session or a date-time.
4///
5/// An `Expiration` is constructible via `Expiration::from()` with an
6/// `Option<OffsetDateTime>` or an `OffsetDateTime`:
7///
8/// * `None` -> `Expiration::Session`
9/// * `Some(OffsetDateTime)` -> `Expiration::DateTime`
10/// * `OffsetDateTime` -> `Expiration::DateTime`
11///
12/// ```rust
13/// use cookie::Expiration;
14/// use time::OffsetDateTime;
15///
16/// let expires = Expiration::from(None);
17/// assert_eq!(expires, Expiration::Session);
18///
19/// let now = OffsetDateTime::now_utc();
20/// let expires = Expiration::from(now);
21/// assert_eq!(expires, Expiration::DateTime(now));
22///
23/// let expires = Expiration::from(Some(now));
24/// assert_eq!(expires, Expiration::DateTime(now));
25/// ```
26#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
27pub enum Expiration {
28 /// Expiration for a "permanent" cookie at a specific date-time.
29 DateTime(OffsetDateTime),
30 /// Expiration for a "session" cookie. Browsers define the notion of a
31 /// "session" and will automatically expire session cookies when they deem
32 /// the "session" to be over. This is typically, but need not be, when the
33 /// browser is closed.
34 Session,
35}
36
37impl Expiration {
38 /// Returns `true` if `self` is an `Expiration::DateTime`.
39 ///
40 /// # Example
41 ///
42 /// ```rust
43 /// use cookie::Expiration;
44 /// use time::OffsetDateTime;
45 ///
46 /// let expires = Expiration::from(None);
47 /// assert!(!expires.is_datetime());
48 ///
49 /// let expires = Expiration::from(OffsetDateTime::now_utc());
50 /// assert!(expires.is_datetime());
51 /// ```
52 pub fn is_datetime(&self) -> bool {
53 match self {
54 Expiration::DateTime(_) => true,
55 Expiration::Session => false
56 }
57 }
58
59 /// Returns `true` if `self` is an `Expiration::Session`.
60 ///
61 /// # Example
62 ///
63 /// ```rust
64 /// use cookie::Expiration;
65 /// use time::OffsetDateTime;
66 ///
67 /// let expires = Expiration::from(None);
68 /// assert!(expires.is_session());
69 ///
70 /// let expires = Expiration::from(OffsetDateTime::now_utc());
71 /// assert!(!expires.is_session());
72 /// ```
73 pub fn is_session(&self) -> bool {
74 match self {
75 Expiration::DateTime(_) => false,
76 Expiration::Session => true
77 }
78 }
79
80 /// Returns the inner `OffsetDateTime` if `self` is a `DateTime`.
81 ///
82 /// # Example
83 ///
84 /// ```rust
85 /// use cookie::Expiration;
86 /// use time::OffsetDateTime;
87 ///
88 /// let expires = Expiration::from(None);
89 /// assert!(expires.datetime().is_none());
90 ///
91 /// let now = OffsetDateTime::now_utc();
92 /// let expires = Expiration::from(now);
93 /// assert_eq!(expires.datetime(), Some(now));
94 /// ```
95 pub fn datetime(self) -> Option<OffsetDateTime> {
96 match self {
97 Expiration::Session => None,
98 Expiration::DateTime(v) => Some(v)
99 }
100 }
101
102 /// Applied `f` to the inner `OffsetDateTime` if `self` is a `DateTime` and
103 /// returns the mapped `Expiration`.
104 ///
105 /// # Example
106 ///
107 /// ```rust
108 /// use cookie::Expiration;
109 /// use time::{OffsetDateTime, Duration};
110 ///
111 /// let now = OffsetDateTime::now_utc();
112 /// let one_week = Duration::weeks(1);
113 ///
114 /// let expires = Expiration::from(now);
115 /// assert_eq!(expires.map(|t| t + one_week).datetime(), Some(now + one_week));
116 ///
117 /// let expires = Expiration::from(None);
118 /// assert_eq!(expires.map(|t| t + one_week).datetime(), None);
119 /// ```
120 pub fn map<F>(self, f: F) -> Self
121 where F: FnOnce(OffsetDateTime) -> OffsetDateTime
122 {
123 match self {
124 Expiration::Session => Expiration::Session,
125 Expiration::DateTime(v) => Expiration::DateTime(f(v)),
126 }
127 }
128}
129
130impl<T: Into<Option<OffsetDateTime>>> From<T> for Expiration {
131 fn from(option: T) -> Self {
132 match option.into() {
133 Some(value) => Expiration::DateTime(value),
134 None => Expiration::Session
135 }
136 }
137}