nutt_web/http/cookie/
mod.rs1use std::collections::HashMap;
2use std::time::SystemTime;
3
4#[derive(Debug, Clone)]
5pub struct CookieRes {
6 name: String,
7 value: String,
8 domain: Option<String>,
9 path: Option<String>,
10 expires: Option<SystemTime>,
11 max_age: Option<u64>,
12 secure: bool,
13 http_only: bool,
14 same_site: Option<SameSite>,
15}
16
17#[derive(Debug, Clone)]
18
19pub struct CookieReq {
20 value: String,
21}
22
23impl CookieReq {
24 pub fn new(value: String) -> Self {
25 Self { value }
26 }
27
28 pub fn get_value(&self) -> String {
29 self.value.to_string()
30 }
31}
32
33#[derive(Debug, Clone)]
34pub enum SameSite {
35 Strict,
36 Lax,
37 None,
38}
39
40impl CookieRes {
41 pub fn new(name: String, value: String) -> Self {
42 Self {
43 name,
44 value,
45 domain: None,
46 path: None,
47 expires: None,
48 max_age: None,
49 secure: false,
50 http_only: false,
51 same_site: None,
52 }
53 }
54
55 pub fn set_domain(&mut self, domain: String) {
56 self.domain = Some(domain);
57 }
58
59 pub fn set_path(&mut self, path: String) {
60 self.path = Some(path);
61 }
62
63 pub fn set_expires(&mut self, expires: SystemTime) {
64 self.expires = Some(expires);
65 }
66
67 pub fn set_max_age(&mut self, max_age: u64) {
68 self.max_age = Some(max_age);
69 }
70
71 pub fn set_secure(&mut self, secure: bool) {
72 self.secure = secure;
73 }
74
75 pub fn set_http_only(&mut self, http_only: bool) {
76 self.http_only = http_only;
77 }
78
79 pub fn set_same_site(&mut self, same_site: SameSite) {
80 self.same_site = Some(same_site);
81 }
82
83 pub fn to_string(&self) -> String {
84 let mut cookie_string = format!("{}={}", self.name, self.value);
85
86 if let Some(ref domain) = self.domain {
87 cookie_string.push_str(&format!("; Domain={}", domain));
88 }
89
90 if let Some(ref path) = self.path {
91 cookie_string.push_str(&format!("; Path={}", path));
92 }
93
94 if let Some(ref expires) = self.expires {
95 if let Ok(expires_time) = expires.duration_since(SystemTime::UNIX_EPOCH) {
96 cookie_string.push_str(&format!(
97 "; Expires={:?}",
98 expires_time.as_secs() ));
100 }
101 }
102
103 if let Some(max_age) = self.max_age {
104 cookie_string.push_str(&format!("; Max-Age={}", max_age));
105 }
106
107 if self.secure {
108 cookie_string.push_str("; Secure");
109 }
110
111 if self.http_only {
112 cookie_string.push_str("; HttpOnly");
113 }
114
115 if let Some(ref same_site) = self.same_site {
116 let same_site_str = match same_site {
117 SameSite::Strict => "Strict",
118 SameSite::Lax => "Lax",
119 SameSite::None => "None",
120 };
121 cookie_string.push_str(&format!("; SameSite={}", same_site_str));
122 }
123
124 cookie_string
125 }
126}
127
128pub struct CookieJarIter<'a> {
129 slice: std::collections::hash_map::Iter<'a, String, CookieReq>,
130}
131
132#[derive(Debug, Clone)]
133pub struct CookieJar {
134 cookies: HashMap<String, CookieReq>,
135}
136
137impl CookieJar {
138 pub fn new() -> Self {
139 Self {
140 cookies: HashMap::new(),
141 }
142 }
143
144 pub(crate) fn push_cookie(&mut self, name: &str, cookie: CookieReq) {
145 self.cookies.insert(name.to_string(), cookie);
146 }
147
148 pub fn iter(&self) -> CookieJarIter {
149 CookieJarIter {
150 slice: self.cookies.iter(),
151 }
152 }
153
154 pub fn get(&self, key: &str) -> Option<&CookieReq> {
155 self.cookies.get(key)
156 }
157}
158
159impl<'a> Iterator for CookieJarIter<'a> {
160 type Item = (&'a String, &'a CookieReq);
161
162 fn next(&mut self) -> Option<Self::Item> {
163 self.slice.next()
164 }
165}