rust_web_server/cookie/
mod.rs1#[cfg(test)]
2mod tests;
3
4#[derive(Debug, Clone, PartialEq, Eq)]
6pub struct Cookie {
7 pub name: String,
8 pub value: String,
9}
10
11pub struct CookieJar {
21 pub cookies: Vec<Cookie>,
22}
23
24impl CookieJar {
25 pub fn parse(header_value: &str) -> CookieJar {
27 let cookies = header_value
28 .split(';')
29 .filter_map(|pair| {
30 let pair = pair.trim();
31 let mut parts = pair.splitn(2, '=');
32 let name = parts.next()?.trim().to_string();
33 let value = parts.next().unwrap_or("").trim().to_string();
34 if name.is_empty() { None } else { Some(Cookie { name, value }) }
35 })
36 .collect();
37 CookieJar { cookies }
38 }
39
40 pub fn get(&self, name: &str) -> Option<&Cookie> {
42 self.cookies.iter().find(|c| c.name == name)
43 }
44}
45
46pub struct SetCookie {
63 pub name: String,
64 pub value: String,
65 pub path: Option<String>,
66 pub domain: Option<String>,
67 pub max_age: Option<i64>,
68 pub secure: bool,
69 pub http_only: bool,
70 pub same_site: Option<String>,
71}
72
73impl SetCookie {
74 pub fn new(name: impl Into<String>, value: impl Into<String>) -> Self {
75 SetCookie {
76 name: name.into(),
77 value: value.into(),
78 path: None,
79 domain: None,
80 max_age: None,
81 secure: false,
82 http_only: false,
83 same_site: None,
84 }
85 }
86
87 pub fn path(mut self, path: impl Into<String>) -> Self {
88 self.path = Some(path.into());
89 self
90 }
91
92 pub fn domain(mut self, domain: impl Into<String>) -> Self {
93 self.domain = Some(domain.into());
94 self
95 }
96
97 pub fn max_age(mut self, seconds: i64) -> Self {
98 self.max_age = Some(seconds);
99 self
100 }
101
102 pub fn secure(mut self) -> Self {
103 self.secure = true;
104 self
105 }
106
107 pub fn http_only(mut self) -> Self {
108 self.http_only = true;
109 self
110 }
111
112 pub fn same_site(mut self, policy: impl Into<String>) -> Self {
113 self.same_site = Some(policy.into());
114 self
115 }
116
117 pub fn build(&self) -> String {
119 let mut s = format!("{}={}", self.name, self.value);
120 if let Some(ref p) = self.path { s.push_str(&format!("; Path={}", p)); }
121 if let Some(ref d) = self.domain { s.push_str(&format!("; Domain={}", d)); }
122 if let Some(age) = self.max_age { s.push_str(&format!("; Max-Age={}", age)); }
123 if self.secure { s.push_str("; Secure"); }
124 if self.http_only { s.push_str("; HttpOnly"); }
125 if let Some(ref ss) = self.same_site { s.push_str(&format!("; SameSite={}", ss)); }
126 s
127 }
128}