cookie_monster/cookie/expires/
mod.rs1use std::fmt::{Debug, Write};
2
3use super::Cookie;
4
5#[cfg(feature = "time")]
6pub mod dep_time;
7
8#[cfg(feature = "chrono")]
9pub mod dep_chrono;
10
11#[cfg(feature = "jiff")]
12pub mod dep_jiff;
13
14const REMOVE: &str = "Thu, 01 Jan 1970 00:00:00 GMT";
15
16#[derive(Clone, Default)]
18pub enum Expires {
19 Remove,
21 #[default]
23 Session,
24 Exp(ExpVal),
25}
26
27#[derive(Clone, Default)]
28pub struct ExpVal {
29 #[cfg(feature = "time")]
30 time: Option<time::OffsetDateTime>,
31 #[cfg(feature = "chrono")]
32 chrono: Option<chrono::DateTime<chrono::Utc>>,
33 #[cfg(feature = "jiff")]
34 jiff: Option<jiff::Zoned>,
35}
36
37impl Expires {
38 pub fn remove() -> Self {
39 #![allow(unreachable_code)]
40
41 #[cfg(feature = "jiff")]
42 return Self::remove_jiff();
43
44 #[cfg(feature = "chrono")]
45 return Self::remove_chrono();
46
47 #[cfg(feature = "time")]
48 return Self::remove_time();
49
50 Self::Remove
51 }
52}
53
54impl Cookie {
55 pub fn is_expires_set(&self) -> bool {
58 matches!(self.expires, Expires::Session)
59 }
60
61 pub(crate) fn serialize_expire(&self, buf: &mut String) -> crate::Result<()> {
62 match &self.expires {
64 #[cfg(feature = "time")]
65 Expires::Exp(ExpVal { time: Some(t), .. }) => dep_time::ser_expires(t, buf),
66 #[cfg(feature = "chrono")]
67 Expires::Exp(ExpVal {
68 chrono: Some(c), ..
69 }) => dep_chrono::ser_expires(c, buf),
70 #[cfg(feature = "jiff")]
71 Expires::Exp(ExpVal { jiff: Some(j), .. }) => dep_jiff::ser_expires(j, buf),
72 Expires::Remove => {
73 let _ = write!(buf, "; Expires={REMOVE}");
74 Ok(())
75 }
76
77 _ => Ok(()),
78 }
79 }
80}
81
82impl PartialEq for Expires {
83 fn eq(&self, other: &Self) -> bool {
84 match (self, other) {
85 (Expires::Remove, Expires::Remove) => true,
86 (Expires::Session, Expires::Session) => true,
87 (Expires::Exp(_s), Expires::Exp(_o)) => {
88 #[cfg(feature = "time")]
90 if _s.time == _o.time {
91 return true;
92 }
93
94 #[cfg(feature = "chrono")]
95 if _s.chrono == _o.chrono {
96 return true;
97 }
98 #[cfg(feature = "jiff")]
99 if _s.jiff == _o.jiff {
100 return true;
101 }
102
103 false
104 }
105 _ => false,
106 }
107 }
108}
109
110impl Debug for Expires {
111 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
112 match self {
113 Self::Remove => write!(f, "{REMOVE}"),
114 Self::Session => write!(f, "Session"),
115 Self::Exp(_exp) => {
116 let mut debug = f.debug_struct("Exp");
117
118 #[cfg(feature = "time")]
119 let debug = debug.field("expires_time", &_exp.time);
120
121 #[cfg(feature = "chrono")]
122 let debug = debug.field("expires_chrono", &_exp.chrono);
123
124 #[cfg(feature = "jiff")]
125 let debug = debug.field("expires_jiff", &_exp.jiff);
126
127 debug.finish()
128 }
129 }
130 }
131}