actix_web_lab/
clear_site_data.rs1use std::{
6 convert::Infallible,
7 fmt,
8 str::{self, FromStr},
9};
10
11use actix_http::{
12 HttpMessage,
13 error::ParseError,
14 header::{
15 CLEAR_SITE_DATA, Header, HeaderName, HeaderValue, InvalidHeaderValue, TryIntoHeaderValue,
16 },
17};
18
19use crate::header::{fmt_comma_delimited_quoted_strings, from_comma_delimited_quoted_strings};
20
21#[derive(Debug, Clone, PartialEq)]
56pub struct ClearSiteData(pub Vec<ClearSiteDataDirective>);
57
58impl_more::forward_deref_and_mut!(ClearSiteData => [ClearSiteDataDirective]);
59
60impl ClearSiteData {
61 #[doc(alias = "wildcard")]
64 pub fn all() -> Self {
65 Self(vec![ClearSiteDataDirective::All])
66 }
67}
68
69impl fmt::Display for ClearSiteData {
70 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
71 fmt_comma_delimited_quoted_strings(f, self.0.iter())
72 }
73}
74
75impl TryIntoHeaderValue for ClearSiteData {
76 type Error = InvalidHeaderValue;
77
78 fn try_into_value(self) -> Result<HeaderValue, Self::Error> {
79 HeaderValue::try_from(self.to_string())
80 }
81}
82
83impl Header for ClearSiteData {
84 fn name() -> HeaderName {
85 CLEAR_SITE_DATA
86 }
87
88 fn parse<M: HttpMessage>(msg: &M) -> Result<Self, ParseError> {
89 let headers = msg.headers().get_all(Self::name());
90
91 let items = from_comma_delimited_quoted_strings(headers)?;
92
93 if items.is_empty() {
94 return Err(ParseError::Header);
95 }
96
97 Ok(ClearSiteData(items))
98 }
99}
100
101#[derive(Debug, Clone, PartialEq)]
105#[non_exhaustive]
106pub enum ClearSiteDataDirective {
107 #[doc(alias = "wildcard")]
112 All,
113
114 Cache,
122
123 ClientHints,
128
129 Cookies,
136
137 Storage,
142
143 ExecutionContexts,
148}
149
150impl ClearSiteDataDirective {
151 const fn directive(&self) -> &'static str {
152 use ClearSiteDataDirective::*;
153
154 match self {
155 All => "*",
156 Cache => "cache",
157 ClientHints => "clientHints",
158 Cookies => "cookies",
159 Storage => "storage",
160 ExecutionContexts => "executionContexts",
161 }
162 }
163}
164
165impl fmt::Display for ClearSiteDataDirective {
166 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
167 f.write_str(self.directive())
168 }
169}
170
171impl FromStr for ClearSiteDataDirective {
172 type Err = Option<Infallible>;
173
174 fn from_str(dir: &str) -> Result<Self, Self::Err> {
175 use ClearSiteDataDirective::*;
176
177 match () {
178 _ if dir == All.directive() => Ok(All),
179 _ if dir == Cache.directive() => Ok(Cache),
180 _ if dir == ClientHints.directive() => Ok(ClientHints),
181 _ if dir == Cookies.directive() => Ok(Cookies),
182 _ if dir == Storage.directive() => Ok(Storage),
183 _ if dir == ExecutionContexts.directive() => Ok(ExecutionContexts),
184
185 _ => Err(None),
186 }
187 }
188}
189
190#[cfg(test)]
191mod tests {
192 use super::*;
193
194 #[test]
195 fn deref() {
196 let mut cache_ctrl = ClearSiteData(vec![]);
197 let _: &[ClearSiteDataDirective] = &cache_ctrl;
198 let _: &mut [ClearSiteDataDirective] = &mut cache_ctrl;
199 }
200}
201
202#[cfg(test)]
203crate::test::header_test_module! {
204 ClearSiteData,
205 tests_parse_and_format {
206 header_round_trip_test!(no_headers, [b""; 0], None);
207 header_round_trip_test!(empty_header, [b""; 1], None);
208 header_round_trip_test!(bad_syntax, [b"foo="], None);
209 header_round_trip_test!(bad_syntax_non_quoted, [b"cache"], None);
210
211 header_round_trip_test!(
212 wildcard,
213 [b"\"*\""],
214 Some(ClearSiteData(vec![
215 ClearSiteDataDirective::All,
216 ]))
217 );
218
219 header_round_trip_test!(
220 single_header,
221 [&b"\"cache\""[..]],
222 Some(ClearSiteData(vec![
223 ClearSiteDataDirective::Cache,
224 ]))
225 );
226
227 header_round_trip_test!(
228 single_header_multiple_directives,
229 [b"\"cache\", \"storage\""],
230 Some(ClearSiteData(vec![
231 ClearSiteDataDirective::Cache,
232 ClearSiteDataDirective::Storage,
233 ]))
234 );
235
236 header_round_trip_test!(
237 multiple_headers,
238 [&b"\"cache\""[..], &b"\"cookies\""[..]],
239 Some(ClearSiteData(vec![
240 ClearSiteDataDirective::Cache,
241 ClearSiteDataDirective::Cookies,
242 ]))
243 );
244 }
245}