trillium_http/headers/
entry.rs1use super::{HeaderName, HeaderValues, KnownHeaderName, UnknownHeaderName};
2use hashbrown::hash_map;
3use std::{
4 collections::btree_map,
5 fmt::{self, Debug, Formatter},
6};
7
8#[derive(Debug)]
10pub enum Entry<'a> {
11 Vacant(VacantEntry<'a>),
14 Occupied(OccupiedEntry<'a>),
16}
17
18pub struct VacantEntry<'a>(pub(super) VacantEntryInner<'a>);
22
23impl Debug for VacantEntry<'_> {
24 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
25 f.debug_struct("VacantEntry")
26 .field("name", &self.name())
27 .finish()
28 }
29}
30
31pub(super) enum VacantEntryInner<'a> {
32 Known(btree_map::VacantEntry<'a, KnownHeaderName, HeaderValues>),
33 Unknown(hash_map::VacantEntry<'a, UnknownHeaderName<'static>, HeaderValues>),
34}
35
36pub struct OccupiedEntry<'a>(pub(super) OccupiedEntryInner<'a>);
40
41impl Debug for OccupiedEntry<'_> {
42 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
43 f.debug_struct("OccupiedEntry")
44 .field("name", &self.name())
45 .field("values", &self.values())
46 .finish()
47 }
48}
49
50pub(super) enum OccupiedEntryInner<'a> {
51 Known(btree_map::OccupiedEntry<'a, KnownHeaderName, HeaderValues>),
52 Unknown(hash_map::OccupiedEntry<'a, UnknownHeaderName<'static>, HeaderValues>),
53}
54
55impl<'a> Entry<'a> {
56 pub fn name(&self) -> HeaderName<'_> {
58 match self {
59 Entry::Vacant(v) => v.name(),
60 Entry::Occupied(o) => o.name(),
61 }
62 }
63
64 pub fn insert(self, values: impl Into<HeaderValues>) -> &'a mut HeaderValues {
68 match self {
69 Entry::Vacant(v) => v.insert(values),
70 Entry::Occupied(mut o) => {
71 o.insert(values);
72 o.into_mut()
73 }
74 }
75 }
76
77 pub fn append(self, values: impl Into<HeaderValues>) -> &'a mut HeaderValues {
80 match self {
81 Entry::Vacant(v) => v.insert(values),
82 Entry::Occupied(mut o) => {
83 o.values_mut().extend(values);
84 o.into_mut()
85 }
86 }
87 }
88
89 pub fn or_insert_with<V: Into<HeaderValues>>(
92 self,
93 values: impl FnOnce() -> V,
94 ) -> &'a mut HeaderValues {
95 match self {
96 Self::Occupied(entry) => entry.into_mut(),
97 Self::Vacant(entry) => entry.insert(values()),
98 }
99 }
100
101 pub fn or_insert(self, values: impl Into<HeaderValues>) -> &'a mut HeaderValues {
104 match self {
105 Entry::Vacant(vacant) => vacant.insert(values),
106 Entry::Occupied(occupied) => occupied.into_mut(),
107 }
108 }
109
110 #[must_use]
113 pub fn and_modify(self, f: impl FnOnce(&mut HeaderValues)) -> Self {
114 match self {
115 Self::Occupied(mut entry) => {
116 f(entry.values_mut());
117 Self::Occupied(entry)
118 }
119 Self::Vacant(entry) => Self::Vacant(entry),
120 }
121 }
122
123 pub fn is_vacant(&self) -> bool {
125 matches!(self, Self::Vacant(_))
126 }
127
128 pub fn is_occupied(&self) -> bool {
130 matches!(self, Self::Occupied(_))
131 }
132
133 pub fn occupied(self) -> Option<OccupiedEntry<'a>> {
135 match self {
136 Entry::Vacant(_) => None,
137 Entry::Occupied(o) => Some(o),
138 }
139 }
140
141 pub fn vacant(self) -> Option<VacantEntry<'a>> {
143 match self {
144 Entry::Vacant(v) => Some(v),
145 Entry::Occupied(_) => None,
146 }
147 }
148}
149
150impl<'a> VacantEntry<'a> {
151 pub fn name(&self) -> HeaderName<'_> {
153 match &self.0 {
154 VacantEntryInner::Known(k) => (*k.key()).into(),
155 VacantEntryInner::Unknown(u) => u.key().reborrow().into(),
156 }
157 }
158
159 pub fn insert(self, values: impl Into<HeaderValues>) -> &'a mut HeaderValues {
161 match self.0 {
162 VacantEntryInner::Known(k) => k.insert(values.into()),
163 VacantEntryInner::Unknown(u) => u.insert(values.into()),
164 }
165 }
166}
167
168impl<'a> OccupiedEntry<'a> {
169 pub fn name(&self) -> HeaderName<'_> {
171 match &self.0 {
172 OccupiedEntryInner::Known(known) => (*known.key()).into(),
173 OccupiedEntryInner::Unknown(unknown) => unknown.key().reborrow().into(),
174 }
175 }
176
177 pub fn values(&self) -> &HeaderValues {
179 match &self.0 {
180 OccupiedEntryInner::Known(known) => known.get(),
181 OccupiedEntryInner::Unknown(unknown) => unknown.get(),
182 }
183 }
184
185 pub fn values_mut(&mut self) -> &mut HeaderValues {
187 match &mut self.0 {
188 OccupiedEntryInner::Known(known) => known.get_mut(),
189 OccupiedEntryInner::Unknown(unknown) => unknown.get_mut(),
190 }
191 }
192
193 pub fn remove_entry(self) -> (HeaderName<'static>, HeaderValues) {
196 match self.0 {
197 OccupiedEntryInner::Known(known) => {
198 let (n, v) = known.remove_entry();
199 (n.into(), v)
200 }
201 OccupiedEntryInner::Unknown(unknown) => {
202 let (n, v) = unknown.remove_entry();
203 (n.into(), v)
204 }
205 }
206 }
207
208 pub fn remove(self) -> HeaderValues {
210 match self.0 {
211 OccupiedEntryInner::Known(known) => known.remove(),
212 OccupiedEntryInner::Unknown(unknown) => unknown.remove(),
213 }
214 }
215
216 pub fn into_mut(self) -> &'a mut HeaderValues {
221 match self.0 {
222 OccupiedEntryInner::Known(k) => k.into_mut(),
223 OccupiedEntryInner::Unknown(u) => u.into_mut(),
224 }
225 }
226
227 pub fn insert(&mut self, values: impl Into<HeaderValues>) -> HeaderValues {
229 match &mut self.0 {
230 OccupiedEntryInner::Known(k) => k.insert(values.into()),
231 OccupiedEntryInner::Unknown(u) => u.insert(values.into()),
232 }
233 }
234
235 pub fn append(&mut self, values: impl Into<HeaderValues>) {
237 self.values_mut().extend(values);
238 }
239}