1use crate::syntax::is_token;
9use arrayvec::{ArrayString, ArrayVec};
10use smallvec::SmallVec;
11use std::{error::Error, fmt, ops::Deref};
12
13#[derive(Clone, Debug, Eq, PartialEq)]
14pub enum FieldError {
15 InvalidName,
16 Duplicate(String),
17 InvalidTrailer(String),
18 InvalidList(String),
19}
20
21impl fmt::Display for FieldError {
22 fn fmt(&self, output: &mut fmt::Formatter<'_>) -> fmt::Result {
23 match self {
24 Self::InvalidName => output.write_str("invalid HTTP field name"),
25 Self::Duplicate(name) => write!(output, "duplicate singleton field: {name}"),
26 Self::InvalidTrailer(name) => {
27 write!(output, "field is not permitted in trailers: {name}")
28 }
29 Self::InvalidList(name) => write!(output, "unterminated quoted value in field: {name}"),
30 }
31 }
32}
33
34impl Error for FieldError {}
35
36#[derive(Clone, Debug, Eq, PartialEq)]
39pub struct Field {
40 name: NameStorage,
41 value: ValueStorage,
42}
43
44#[derive(Clone, Debug, Eq, PartialEq)]
47enum NameStorage {
48 Inline(ArrayString<24>),
49 Heap(String),
50}
51impl NameStorage {
52 #[inline]
53 fn new(value: &str) -> Self {
54 match ArrayString::from(value) {
55 Ok(value) => Self::Inline(value),
56 Err(_) => Self::Heap(value.to_owned()),
57 }
58 }
59}
60impl Deref for NameStorage {
61 type Target = str;
62 fn deref(&self) -> &str {
63 match self {
64 Self::Inline(value) => value.as_str(),
65 Self::Heap(value) => value,
66 }
67 }
68}
69
70#[derive(Clone, Debug, Eq, PartialEq)]
73enum ValueStorage {
74 Inline(ArrayVec<u8, 24>, bool),
75 Heap(Vec<u8>, bool),
76}
77impl ValueStorage {
78 #[inline]
79 fn new(value: &[u8]) -> Self {
80 let dangerous = value.iter().fold(false, |found, byte| {
82 found | matches!(byte, b'\r' | b'\n' | 0)
83 });
84 let mut inline = ArrayVec::new();
85 if inline.try_extend_from_slice(value).is_ok() {
86 Self::Inline(inline, dangerous)
87 } else {
88 Self::Heap(value.to_vec(), dangerous)
89 }
90 }
91}
92impl Deref for ValueStorage {
93 type Target = [u8];
94 fn deref(&self) -> &[u8] {
95 match self {
96 Self::Inline(value, _) => value.as_slice(),
97 Self::Heap(value, _) => value,
98 }
99 }
100}
101
102impl Field {
103 #[inline]
104 pub fn new(name: impl AsRef<str>, value: impl AsRef<[u8]>) -> Result<Self, FieldError> {
105 let name = name.as_ref();
106 if !is_token(name.as_bytes()) {
107 return Err(FieldError::InvalidName);
108 }
109 Ok(Self {
110 name: NameStorage::new(name),
111 value: ValueStorage::new(value.as_ref()),
112 })
113 }
114
115 pub fn name(&self) -> &str {
116 &self.name
117 }
118 pub fn value(&self) -> &[u8] {
119 &self.value
120 }
121 pub fn has_dangerous_bytes(&self) -> bool {
126 match self.value {
127 ValueStorage::Inline(_, dangerous) | ValueStorage::Heap(_, dangerous) => dangerous,
128 }
129 }
130}
131
132#[derive(Clone, Debug, Default, Eq, PartialEq)]
136pub struct Fields {
137 pub(crate) pairs: SmallVec<[Field; 1]>,
138}
139
140impl Fields {
141 #[inline]
142 pub fn new() -> Self {
143 Self::default()
144 }
145 #[inline]
148 pub fn with_capacity(capacity: usize) -> Self {
149 Self {
150 pairs: SmallVec::with_capacity(capacity),
151 }
152 }
153 #[inline]
155 pub fn reserve(&mut self, additional: usize) {
156 self.pairs.reserve(additional);
157 }
158 pub fn try_from_pairs<N: AsRef<str>, V: AsRef<[u8]>>(
159 pairs: impl IntoIterator<Item = (N, V)>,
160 ) -> Result<Self, FieldError> {
161 let mut fields = Self::new();
162 for (name, value) in pairs {
163 fields.add(name, value)?;
164 }
165 Ok(fields)
166 }
167 pub fn pairs(&self) -> &[Field] {
168 &self.pairs
169 }
170 pub fn len(&self) -> usize {
171 self.pairs.len()
172 }
173 pub fn is_empty(&self) -> bool {
174 self.pairs.is_empty()
175 }
176 pub fn values<'a>(&'a self, name: &'a str) -> impl Iterator<Item = &'a [u8]> + 'a {
177 self.pairs
178 .iter()
179 .filter(move |field| field.name().eq_ignore_ascii_case(name))
180 .map(Field::value)
181 }
182 pub fn contains(&self, name: &str) -> bool {
183 self.pairs
184 .iter()
185 .any(|field| field.name().eq_ignore_ascii_case(name))
186 }
187 #[inline]
188 pub fn add(
189 &mut self,
190 name: impl AsRef<str>,
191 value: impl AsRef<[u8]>,
192 ) -> Result<(), FieldError> {
193 self.append(Field::new(name, value)?)
194 }
195 #[inline]
196 pub fn append(&mut self, field: Field) -> Result<(), FieldError> {
197 self.pairs.push(field);
198 Ok(())
199 }
200 pub fn set(
201 &mut self,
202 name: impl AsRef<str>,
203 value: impl AsRef<[u8]>,
204 ) -> Result<(), FieldError> {
205 let field = Field::new(name, value)?;
206 self.remove(field.name());
207 self.pairs.push(field);
208 Ok(())
209 }
210 pub fn remove(&mut self, name: &str) -> usize {
211 let original = self.len();
212 self.retain(|field| !field.name().eq_ignore_ascii_case(name));
213 original - self.len()
214 }
215 pub fn retain(&mut self, mut keep: impl FnMut(&Field) -> bool) {
216 self.pairs.retain(|field| keep(field));
217 }
218 pub fn clear(&mut self) {
219 self.pairs.clear();
220 }
221 pub fn split_off(&mut self, at: usize) -> Self {
222 Self {
223 pairs: self.pairs.drain(at..).collect(),
224 }
225 }
226}
227impl IntoIterator for Fields {
228 type Item = Field;
229 type IntoIter = smallvec::IntoIter<[Field; 1]>;
230 fn into_iter(self) -> Self::IntoIter {
231 self.pairs.into_iter()
232 }
233}
234impl Extend<Field> for Fields {
235 fn extend<T: IntoIterator<Item = Field>>(&mut self, iter: T) {
236 self.pairs.extend(iter);
237 }
238}
239impl FromIterator<Field> for Fields {
240 fn from_iter<T: IntoIterator<Item = Field>>(iter: T) -> Self {
241 Self {
242 pairs: iter.into_iter().collect(),
243 }
244 }
245}