li_http_types/cache/cache_control/
cache_control.rs1use crate::cache::CacheDirective;
2use crate::headers::{HeaderName, HeaderValue, Headers, ToHeaderValues, CACHE_CONTROL};
3
4use std::fmt::{self, Debug, Write};
5use std::iter::Iterator;
6use std::option;
7use std::slice;
8
9pub struct CacheControl {
33 entries: Vec<CacheDirective>,
34}
35
36impl CacheControl {
37 pub fn new() -> Self {
39 Self { entries: vec![] }
40 }
41
42 pub fn from_headers(headers: impl AsRef<Headers>) -> crate::Result<Option<Self>> {
44 let mut entries = vec![];
45 let headers = match headers.as_ref().get(CACHE_CONTROL) {
46 Some(headers) => headers,
47 None => return Ok(None),
48 };
49
50 for value in headers {
51 for part in value.as_str().trim().split(',') {
52 if let Some(entry) = CacheDirective::from_str(part)? {
55 entries.push(entry);
56 }
57 }
58 }
59
60 Ok(Some(Self { entries }))
61 }
62
63 pub fn apply(&self, mut headers: impl AsMut<Headers>) {
65 headers.as_mut().insert(CACHE_CONTROL, self.value());
66 }
67
68 pub fn name(&self) -> HeaderName {
70 CACHE_CONTROL
71 }
72
73 pub fn value(&self) -> HeaderValue {
75 let mut output = String::new();
76 for (n, directive) in self.entries.iter().enumerate() {
77 let directive: HeaderValue = directive.clone().into();
78 match n {
79 0 => write!(output, "{}", directive).unwrap(),
80 _ => write!(output, ", {}", directive).unwrap(),
81 };
82 }
83
84 unsafe { HeaderValue::from_bytes_unchecked(output.into()) }
86 }
87 pub fn push(&mut self, directive: CacheDirective) {
89 self.entries.push(directive);
90 }
91
92 pub fn iter(&self) -> Iter<'_> {
94 Iter {
95 inner: self.entries.iter(),
96 }
97 }
98
99 pub fn iter_mut(&mut self) -> IterMut<'_> {
101 IterMut {
102 inner: self.entries.iter_mut(),
103 }
104 }
105}
106
107impl IntoIterator for CacheControl {
108 type Item = CacheDirective;
109 type IntoIter = IntoIter;
110
111 #[inline]
112 fn into_iter(self) -> Self::IntoIter {
113 IntoIter {
114 inner: self.entries.into_iter(),
115 }
116 }
117}
118
119impl<'a> IntoIterator for &'a CacheControl {
120 type Item = &'a CacheDirective;
121 type IntoIter = Iter<'a>;
122
123 #[inline]
124 fn into_iter(self) -> Self::IntoIter {
125 self.iter()
126 }
127}
128
129impl<'a> IntoIterator for &'a mut CacheControl {
130 type Item = &'a mut CacheDirective;
131 type IntoIter = IterMut<'a>;
132
133 #[inline]
134 fn into_iter(self) -> Self::IntoIter {
135 self.iter_mut()
136 }
137}
138
139#[derive(Debug)]
141pub struct IntoIter {
142 inner: std::vec::IntoIter<CacheDirective>,
143}
144
145impl Iterator for IntoIter {
146 type Item = CacheDirective;
147
148 fn next(&mut self) -> Option<Self::Item> {
149 self.inner.next()
150 }
151
152 #[inline]
153 fn size_hint(&self) -> (usize, Option<usize>) {
154 self.inner.size_hint()
155 }
156}
157
158#[derive(Debug)]
160pub struct Iter<'a> {
161 inner: slice::Iter<'a, CacheDirective>,
162}
163
164impl<'a> Iterator for Iter<'a> {
165 type Item = &'a CacheDirective;
166
167 fn next(&mut self) -> Option<Self::Item> {
168 self.inner.next()
169 }
170
171 #[inline]
172 fn size_hint(&self) -> (usize, Option<usize>) {
173 self.inner.size_hint()
174 }
175}
176
177#[derive(Debug)]
179pub struct IterMut<'a> {
180 inner: slice::IterMut<'a, CacheDirective>,
181}
182
183impl<'a> Iterator for IterMut<'a> {
184 type Item = &'a mut CacheDirective;
185
186 fn next(&mut self) -> Option<Self::Item> {
187 self.inner.next()
188 }
189
190 #[inline]
191 fn size_hint(&self) -> (usize, Option<usize>) {
192 self.inner.size_hint()
193 }
194}
195
196impl ToHeaderValues for CacheControl {
197 type Iter = option::IntoIter<HeaderValue>;
198 fn to_header_values(&self) -> crate::Result<Self::Iter> {
199 Ok(self.value().to_header_values().unwrap())
201 }
202}
203
204impl Debug for CacheControl {
205 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
206 let mut list = f.debug_list();
207 for directive in &self.entries {
208 list.entry(directive);
209 }
210 list.finish()
211 }
212}