trillium_http/headers/
header_values.rs1use crate::HeaderValue;
2use smallvec::{smallvec, SmallVec};
3use smartcow::SmartCow;
4use std::{
5 borrow::Cow,
6 fmt::{Debug, Formatter, Result},
7 ops::{Deref, DerefMut},
8};
9
10#[derive(Clone, Eq, PartialEq)]
14pub struct HeaderValues(SmallVec<[HeaderValue; 1]>);
15impl Deref for HeaderValues {
16 type Target = [HeaderValue];
17
18 fn deref(&self) -> &Self::Target {
19 &self.0
20 }
21}
22
23#[cfg(feature = "serde")]
24impl serde::Serialize for HeaderValues {
25 fn serialize<S>(&self, serializer: S) -> std::prelude::v1::Result<S::Ok, S::Error>
26 where
27 S: serde::Serializer,
28 {
29 match self.one() {
30 Some(one) => one.serialize(serializer),
31 None => self.0.serialize(serializer),
32 }
33 }
34}
35
36impl Default for HeaderValues {
37 fn default() -> Self {
38 Self(SmallVec::with_capacity(1))
39 }
40}
41
42impl DerefMut for HeaderValues {
43 fn deref_mut(&mut self) -> &mut Self::Target {
44 &mut self.0
45 }
46}
47
48impl Debug for HeaderValues {
49 fn fmt(&self, f: &mut Formatter<'_>) -> Result {
50 match self.one() {
51 Some(one) => Debug::fmt(one, f),
52 None => f.debug_list().entries(&self.0).finish(),
53 }
54 }
55}
56
57impl PartialEq<[&str]> for HeaderValues {
58 fn eq(&self, other: &[&str]) -> bool {
59 &**self == other
60 }
61}
62
63impl IntoIterator for HeaderValues {
64 type Item = HeaderValue;
65
66 type IntoIter = smallvec::IntoIter<[HeaderValue; 1]>;
67
68 fn into_iter(self) -> Self::IntoIter {
69 self.0.into_iter()
70 }
71}
72
73impl<'a> IntoIterator for &'a HeaderValues {
74 type Item = &'a HeaderValue;
75
76 type IntoIter = std::slice::Iter<'a, HeaderValue>;
77
78 fn into_iter(self) -> Self::IntoIter {
79 self.0.iter()
80 }
81}
82
83impl<I> FromIterator<I> for HeaderValues
84where
85 I: Into<HeaderValue>,
86{
87 fn from_iter<T: IntoIterator<Item = I>>(iter: T) -> Self {
88 Self(iter.into_iter().map(Into::into).collect())
89 }
90}
91
92impl HeaderValues {
93 #[must_use]
96 pub fn new() -> Self {
97 Self(SmallVec::with_capacity(1))
98 }
99
100 pub fn as_str(&self) -> Option<&str> {
105 self.one().and_then(HeaderValue::as_str)
106 }
107
108 pub(crate) fn as_lower(&self) -> Option<SmartCow<'_>> {
109 self.one().and_then(HeaderValue::as_lower)
110 }
111
112 pub fn one(&self) -> Option<&HeaderValue> {
117 if self.len() == 1 {
118 self.0.first()
119 } else {
120 None
121 }
122 }
123
124 pub fn append(&mut self, value: impl Into<HeaderValue>) {
126 self.0.push(value.into());
127 }
128
129 pub fn extend(&mut self, values: impl Into<HeaderValues>) {
131 let values = values.into();
132 self.0.extend(values);
133 }
134}
135
136impl From<&'static [u8]> for HeaderValues {
143 fn from(value: &'static [u8]) -> Self {
144 HeaderValue::from(value).into()
145 }
146}
147
148impl From<Vec<u8>> for HeaderValues {
149 fn from(value: Vec<u8>) -> Self {
150 HeaderValue::from(value).into()
151 }
152}
153
154impl From<String> for HeaderValues {
155 fn from(value: String) -> Self {
156 HeaderValue::from(value).into()
157 }
158}
159
160impl From<&'static str> for HeaderValues {
161 fn from(value: &'static str) -> Self {
162 HeaderValue::from(value).into()
163 }
164}
165
166impl From<Cow<'static, str>> for HeaderValues {
167 fn from(value: Cow<'static, str>) -> Self {
168 HeaderValue::from(value).into()
169 }
170}
171
172impl From<HeaderValue> for HeaderValues {
173 fn from(v: HeaderValue) -> Self {
174 Self(smallvec![v])
175 }
176}
177
178impl<HV> From<Vec<HV>> for HeaderValues
179where
180 HV: Into<HeaderValue>,
181{
182 fn from(v: Vec<HV>) -> Self {
183 Self(v.into_iter().map(Into::into).collect())
184 }
185}