turbopack_dev_server/source/
headers.rs1use std::{collections::BTreeMap, hash::Hash, mem::replace, ops::DerefMut};
2
3use bincode::{Decode, Encode};
4use turbo_tasks::trace::TraceRawVcs;
5
6#[turbo_tasks::task_input]
8#[derive(Clone, Debug, PartialEq, Eq, Default, Hash, TraceRawVcs, Encode, Decode)]
9pub struct Headers(BTreeMap<String, HeaderValue>);
10
11#[turbo_tasks::task_input]
14#[derive(Clone, Debug, PartialEq, Eq, Hash, TraceRawVcs, Encode, Decode)]
15pub enum HeaderValue {
16 SingleString(String),
17 SingleBytes(Vec<u8>),
18 MultiStrings(Vec<String>),
19 MultiBytes(Vec<Vec<u8>>),
20}
21
22impl std::ops::Deref for Headers {
23 type Target = BTreeMap<String, HeaderValue>;
24 fn deref(&self) -> &Self::Target {
25 &self.0
26 }
27}
28
29impl DerefMut for Headers {
30 fn deref_mut(&mut self) -> &mut Self::Target {
31 &mut self.0
32 }
33}
34
35impl HeaderValue {
36 pub fn extend_with_string(&mut self, new: String) {
39 *self = match replace(self, HeaderValue::SingleBytes(Vec::new())) {
40 HeaderValue::SingleString(s) => HeaderValue::MultiStrings(vec![s, new]),
41 HeaderValue::SingleBytes(b) => HeaderValue::MultiBytes(vec![b, new.into()]),
42 HeaderValue::MultiStrings(mut v) => {
43 v.push(new);
44 HeaderValue::MultiStrings(v)
45 }
46 HeaderValue::MultiBytes(mut v) => {
47 v.push(new.into());
48 HeaderValue::MultiBytes(v)
49 }
50 }
51 }
52 pub fn extend_with_bytes(&mut self, new: Vec<u8>) {
55 *self = match replace(self, HeaderValue::SingleBytes(Vec::new())) {
56 HeaderValue::SingleString(s) => HeaderValue::MultiBytes(vec![s.into(), new]),
57 HeaderValue::SingleBytes(b) => HeaderValue::MultiBytes(vec![b, new]),
58 HeaderValue::MultiStrings(v) => {
59 let mut v: Vec<Vec<u8>> = v.into_iter().map(|s| s.into()).collect();
60 v.push(new);
61 HeaderValue::MultiBytes(v)
62 }
63 HeaderValue::MultiBytes(mut v) => {
64 v.push(new);
65 HeaderValue::MultiBytes(v)
66 }
67 }
68 }
69
70 pub fn contains(&self, string_value: &str) -> bool {
71 match self {
72 HeaderValue::SingleString(s) => s.contains(string_value),
73 HeaderValue::MultiStrings(s) => s.iter().any(|s| s.contains(string_value)),
74 _ => false,
75 }
76 }
77}