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.as_bytes().len() + 2 + self.value.len() + 2
121 }
122
123 pub fn name_bytes(&self) -> &'static [u8] {
124 self.name.as_bytes()
125 }
126
127 pub fn value_bytes(&self) -> &[u8] {
128 self.value.as_bytes()
129 }
130}
131
132impl<'req> From<InlineHeaderValue> for HeaderValueInner<'req> {
133 fn from(value: InlineHeaderValue) -> Self {
134 Self::Inline(value)
135 }
136}
137
138impl<'req> From<Bytes<Borrowed<'req>>> for HeaderValueInner<'req> {
139 fn from(value: Bytes<Borrowed<'req>>) -> Self {
140 Self::Borrowed(value)
141 }
142}
143
144impl<'req> From<Bytes<Retained>> for HeaderValueInner<'req> {
145 fn from(value: Bytes<Retained>) -> Self {
146 Self::Retained(value)
147 }
148}
149
150impl<'req> From<Shared> for HeaderValueInner<'req> {
151 fn from(value: Shared) -> Self {
152 Self::Shared(value)
153 }
154}
155
156impl<'req> From<Owned> for HeaderValueInner<'req> {
157 fn from(value: Owned) -> Self {
158 Self::Shared(value.freeze())
159 }
160}
161
162impl<'req> From<String> for HeaderValueInner<'req> {
163 fn from(value: String) -> Self {
164 Self::Shared(Shared::from(value.into_bytes()))
165 }
166}
167
168impl<'req> From<&'static str> for HeaderValueInner<'req> {
169 fn from(value: &'static str) -> Self {
170 Self::Static(value.as_bytes())
171 }
172}