sark_core/http/response/direct/
value.rs1use o3::buffer::{Borrowed, Bytes, Owned, Retained, Shared};
2
3use super::headers::HeaderNameToken;
4
5#[derive(Clone)]
6pub enum HeaderValueInner<'req> {
7 Static(&'static [u8]),
8 Inline(InlineHeaderValue),
9 Shared(Shared),
10 Borrowed(Bytes<Borrowed<'req>>),
11 Retained(Bytes<Retained>),
12}
13
14#[derive(Clone, Copy)]
15pub struct InlineHeaderValue {
16 bytes: [u8; 31],
17 len: u8,
18}
19
20impl InlineHeaderValue {
21 pub fn new(value: &[u8]) -> Self {
22 assert!(
23 value.len() <= 31,
24 "inline header value overflow: max 31, got {}",
25 value.len()
26 );
27 let mut bytes = [0u8; 31];
28 bytes[..value.len()].copy_from_slice(value);
29 Self {
30 bytes,
31 len: value.len() as u8,
32 }
33 }
34
35 pub fn as_bytes(&self) -> &[u8] {
36 &self.bytes[..usize::from(self.len)]
37 }
38}
39
40impl std::fmt::Debug for InlineHeaderValue {
41 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
42 f.debug_struct("InlineHeaderValue")
43 .field("len", &self.len)
44 .finish()
45 }
46}
47
48impl<'req> std::fmt::Debug for HeaderValueInner<'req> {
49 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
50 match self {
51 Self::Static(value) => f
52 .debug_struct("HeaderValue::Static")
53 .field("len", &value.len())
54 .finish(),
55 Self::Inline(value) => f
56 .debug_struct("HeaderValue::Inline")
57 .field("len", &value.as_bytes().len())
58 .finish(),
59 Self::Shared(value) => f
60 .debug_struct("HeaderValue::Shared")
61 .field("len", &value.len())
62 .finish(),
63 Self::Borrowed(value) => f
64 .debug_struct("HeaderValue::Borrowed")
65 .field("len", &value.len())
66 .finish(),
67 Self::Retained(value) => f
68 .debug_struct("HeaderValue::Retained")
69 .field("len", &value.len())
70 .finish(),
71 }
72 }
73}
74
75impl<'req> HeaderValueInner<'req> {
76 pub fn as_bytes(&self) -> &[u8] {
77 match self {
78 Self::Static(value) => value,
79 Self::Inline(value) => value.as_bytes(),
80 Self::Shared(value) => value.as_ref(),
81 Self::Borrowed(value) => value.as_slice(),
82 Self::Retained(value) => value.as_slice(),
83 }
84 }
85
86 pub fn len(&self) -> usize {
87 self.as_bytes().len()
88 }
89
90 pub fn is_empty(&self) -> bool {
91 self.as_bytes().is_empty()
92 }
93}
94
95#[derive(Clone, Debug)]
96pub struct HeaderItem<'req> {
97 pub(super) name: HeaderNameToken,
98 pub(super) value: HeaderValueInner<'req>,
99}
100
101impl<'req> HeaderItem<'req> {
102 pub fn from_value<V>(name: HeaderNameToken, value: V) -> Self
103 where
104 V: Into<HeaderValueInner<'req>>,
105 {
106 Self {
107 name,
108 value: value.into(),
109 }
110 }
111
112 pub(crate) fn placeholder() -> Self {
113 Self {
114 name: HeaderNameToken::empty_placeholder(),
115 value: HeaderValueInner::Static(&[]),
116 }
117 }
118
119 pub fn wire_len(&self) -> usize {
120 self.name
121 .as_bytes()
122 .len()
123 .saturating_add(2)
124 .saturating_add(self.value.len())
125 .saturating_add(2)
126 }
127
128 pub fn name_bytes(&self) -> &'static [u8] {
129 self.name.as_bytes()
130 }
131
132 pub fn value_bytes(&self) -> &[u8] {
133 self.value.as_bytes()
134 }
135}
136
137impl<'req> From<InlineHeaderValue> for HeaderValueInner<'req> {
138 fn from(value: InlineHeaderValue) -> Self {
139 Self::Inline(value)
140 }
141}
142
143impl<'req> From<Bytes<Borrowed<'req>>> for HeaderValueInner<'req> {
144 fn from(value: Bytes<Borrowed<'req>>) -> Self {
145 Self::Borrowed(value)
146 }
147}
148
149impl<'req> From<Bytes<Retained>> for HeaderValueInner<'req> {
150 fn from(value: Bytes<Retained>) -> Self {
151 Self::Retained(value)
152 }
153}
154
155impl<'req> From<Shared> for HeaderValueInner<'req> {
156 fn from(value: Shared) -> Self {
157 Self::Shared(value)
158 }
159}
160
161impl<'req> From<Owned> for HeaderValueInner<'req> {
162 fn from(value: Owned) -> Self {
163 Self::Shared(value.freeze())
164 }
165}
166
167impl<'req> From<String> for HeaderValueInner<'req> {
168 fn from(value: String) -> Self {
169 Self::Shared(Shared::from(value.into_bytes()))
170 }
171}
172
173impl<'req> From<&'static str> for HeaderValueInner<'req> {
174 fn from(value: &'static str) -> Self {
175 Self::Static(value.as_bytes())
176 }
177}