viz_core/middleware/
helper.rs1use std::time::Duration;
4
5use crate::types::{Cookie, Cookies, SameSite};
6
7#[derive(Debug)]
9pub struct CookieOptions {
10 pub name: &'static str,
12 pub path: &'static str,
14 pub secure: bool,
16 pub http_only: bool,
18 pub max_age: Option<Duration>,
20 pub domain: Option<&'static str>,
22 pub same_site: Option<SameSite>,
24}
25
26impl CookieOptions {
27 pub const MAX_AGE: u64 = 3600 * 24;
29
30 #[must_use]
32 pub fn new(name: &'static str) -> Self {
33 Self::default().name(name)
34 }
35
36 #[must_use]
38 pub const fn name(mut self, name: &'static str) -> Self {
39 self.name = name;
40 self
41 }
42
43 #[must_use]
45 pub fn max_age(mut self, max_age: Duration) -> Self {
46 self.max_age.replace(max_age);
47 self
48 }
49
50 #[must_use]
52 pub fn domain(mut self, domain: &'static str) -> Self {
53 self.domain.replace(domain);
54 self
55 }
56
57 #[must_use]
59 pub const fn path(mut self, path: &'static str) -> Self {
60 self.path = path;
61 self
62 }
63
64 #[must_use]
66 pub const fn secure(mut self, secure: bool) -> Self {
67 self.secure = secure;
68 self
69 }
70
71 #[must_use]
73 pub const fn http_only(mut self, http_only: bool) -> Self {
74 self.http_only = http_only;
75 self
76 }
77
78 #[must_use]
80 pub fn same_site(mut self, same_site: SameSite) -> Self {
81 self.same_site.replace(same_site);
82 self
83 }
84
85 pub fn into_cookie(&self, value: impl Into<String>) -> Cookie<'_> {
91 let mut cookie = Cookie::new(self.name, value.into());
92
93 cookie.set_path(self.path);
94 cookie.set_secure(self.secure);
95 cookie.set_http_only(self.http_only);
96 cookie.set_same_site(self.same_site);
97
98 if let Some(domain) = self.domain {
99 cookie.set_domain(domain);
100 }
101 if let Some(max_age) = self.max_age {
102 cookie
103 .set_max_age(::cookie::time::Duration::try_from(max_age).expect(
104 "`std::time::Duration` cannot be converted to `cookie::ime::Duration`",
105 ));
106 }
107
108 cookie
109 }
110}
111
112impl Default for CookieOptions {
113 fn default() -> Self {
114 Self {
115 domain: None,
116 secure: true,
117 http_only: true,
118 path: "/",
119 name: "viz.sid",
120 same_site: Some(SameSite::Lax),
121 max_age: Some(Duration::from_secs(Self::MAX_AGE)),
122 }
123 }
124}
125
126#[cfg(not(feature = "cookie-private"))]
128pub trait Cookieable {
129 fn options(&self) -> &CookieOptions;
131
132 fn get_cookie<'a>(&'a self, cookies: &'a Cookies) -> Option<Cookie<'a>> {
134 cookies.get(self.options().name)
135 }
136
137 fn remove_cookie<'a>(&'a self, cookies: &'a Cookies) {
139 cookies.remove(self.options().name);
140 }
141
142 fn set_cookie<'a>(&'a self, cookies: &'a Cookies, value: impl Into<String>) {
144 cookies.add(self.options().into_cookie(value));
145 }
146}
147
148#[cfg(feature = "cookie-private")]
150pub trait Cookieable {
151 fn options(&self) -> &CookieOptions;
153
154 fn get_cookie<'a>(&'a self, cookies: &'a Cookies) -> Option<Cookie<'a>> {
156 cookies.private_get(self.options().name)
157 }
158
159 fn remove_cookie<'a>(&'a self, cookies: &'a Cookies) {
161 cookies.private_remove(self.options().name);
162 }
163
164 fn set_cookie<'a>(&'a self, cookies: &'a Cookies, value: impl Into<String>) {
166 cookies.private_add(self.options().into_cookie(value));
167 }
168}