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