sark_http/field/metadata/map/
mod.rs1use std::mem;
4
5use metadata::packed::{Iter, RangeIter, prefix::Prefix};
6use o3::{
7 alloc,
8 alloc::{BoxSliceExt as _, VecExt as _},
9 buffer::write::{self, Sink as _, consume},
10};
11use record::Entry;
12
13use crate::field::metadata;
14
15pub mod record;
16
17#[derive(PartialEq, Eq)]
18pub struct Owned {
19 pub name: Vec<u8>,
20 pub value: Vec<u8>,
21 pub indexing: crate::field::Indexing,
22}
23
24impl Owned {
25 pub fn try_new(name: &[u8], value: &[u8]) -> Result<Self, alloc::Exhausted> {
26 Ok(Self {
27 name: Box::<[u8]>::try_copy(name)?.into_vec(),
28 value: Box::<[u8]>::try_copy(value)?.into_vec(),
29 indexing: crate::field::Indexing::Allowed,
30 })
31 }
32
33 pub fn as_ref(&self) -> Entry<'_> {
34 Entry::new(&self.name, &self.value).with_index(self.indexing)
35 }
36
37 pub fn with_index(mut self, indexing: crate::field::Indexing) -> Self {
38 self.indexing = indexing;
39 self
40 }
41}
42
43impl TryFrom<Entry<'_>> for Owned {
44 type Error = alloc::Exhausted;
45
46 fn try_from(field: Entry<'_>) -> Result<Self, Self::Error> {
47 Ok(Self::try_new(field.name, field.value)?.with_index(field.indexing))
48 }
49}
50
51#[derive(Clone)]
52pub struct OwnedIter<'a> {
53 fields: &'a [Owned],
54}
55
56impl<'a> Iterator for OwnedIter<'a> {
57 type Item = Entry<'a>;
58
59 fn next(&mut self) -> Option<Self::Item> {
60 let (field, rest) = self.fields.split_first()?;
61 self.fields = rest;
62 Some(field.as_ref())
63 }
64
65 fn size_hint(&self) -> (usize, Option<usize>) {
66 let len = self.fields.len();
67 (len, Some(len))
68 }
69}
70
71impl ExactSizeIterator for OwnedIter<'_> {}
72
73impl metadata::Metadata for Vec<Owned> {
74 type Iter<'a> = OwnedIter<'a>;
75
76 fn fields(&self) -> Self::Iter<'_> {
77 OwnedIter {
78 fields: self.as_slice(),
79 }
80 }
81}
82
83#[derive(PartialEq, Eq)]
85pub struct Fields<S> {
86 bytes: S,
87}
88
89#[derive(Clone, Debug, PartialEq, Eq)]
90pub enum Error {
91 Reserve(alloc::Error),
92 Write(consume::Error),
93 ComponentTooLarge {
94 len: usize,
95 },
96 CapacityOverflow {
97 current: usize,
98 name: usize,
99 value: usize,
100 },
101 ValueLengthMismatch {
102 expected: usize,
103 actual: usize,
104 },
105}
106
107fn packed_len(len: usize) -> Result<u32, usize> {
108 if len > u32::MAX as usize {
109 return Err(len);
110 }
111 Ok(len as u32)
112}
113
114impl From<usize> for Error {
115 fn from(len: usize) -> Self {
116 Self::ComponentTooLarge { len }
117 }
118}
119
120impl<S: AsRef<[u8]>> metadata::Metadata for Fields<S> {
121 type Iter<'a>
122 = Iter<'a>
123 where
124 S: 'a;
125
126 fn fields(&self) -> Self::Iter<'_> {
127 Iter::new(self.bytes.as_ref())
128 }
129}
130
131impl Fields<Vec<u8>> {
132 pub const fn new() -> Self {
133 Self { bytes: Vec::new() }
134 }
135
136 pub fn try_with(capacity: usize) -> Result<Self, Error> {
137 Ok(Self {
138 bytes: Vec::try_new(capacity).map_err(Error::Reserve)?,
139 })
140 }
141
142 pub fn push(&mut self, name: &[u8], value: &[u8]) -> Result<(), Error> {
143 self.push_entry(Entry::new(name, value))
144 }
145
146 pub fn push_entry(&mut self, field: Entry<'_>) -> Result<(), Error> {
147 Space::new(
148 &mut self.bytes,
149 field.name.len(),
150 field.value.len(),
151 field.indexing,
152 )?
153 .generated(field.name, |writer| writer.write_slice(field.value))?
154 .commit();
155 Ok(())
156 }
157
158 pub fn push_encoded<F>(&mut self, name: &[u8], vlen: usize, encode: F) -> Result<(), Error>
162 where
163 F: FnOnce(&mut ValueWriter<'_>) -> Result<(), consume::Error>,
164 {
165 self.push_with(name, vlen, crate::field::Indexing::Allowed, encode)
166 }
167
168 pub fn push_with<F>(
170 &mut self,
171 name: &[u8],
172 vlen: usize,
173 indexing: crate::field::Indexing,
174 encode: F,
175 ) -> Result<(), Error>
176 where
177 F: FnOnce(&mut ValueWriter<'_>) -> Result<(), consume::Error>,
178 {
179 Space::new(&mut self.bytes, name.len(), vlen, indexing)?
180 .generated(name, encode)?
181 .commit();
182 Ok(())
183 }
184}
185
186impl<S: AsRef<[u8]>> Fields<S> {
187 pub fn iter(&self) -> Iter<'_> {
188 Iter::new(self.bytes.as_ref())
189 }
190
191 pub fn get(&self, name: &[u8]) -> Option<&[u8]> {
192 self.iter()
193 .find(|field| field.name == name)
194 .map(|field| field.value)
195 }
196
197 pub fn as_bytes(&self) -> &[u8] {
198 self.bytes.as_ref()
199 }
200
201 pub fn ranges(&self) -> RangeIter<'_> {
202 RangeIter::new(self.bytes.as_ref())
203 }
204}
205
206impl Default for Fields<Vec<u8>> {
207 fn default() -> Self {
208 Self::new()
209 }
210}
211
212#[repr(transparent)]
214pub struct ValueWriter<'a>(write::Staged<'a, usize>);
215
216impl write::Sink for ValueWriter<'_> {
217 type Error = consume::Error;
218
219 fn write_slice(&mut self, bytes: &[u8]) -> Result<(), Self::Error> {
220 self.0.write_slice(bytes)
221 }
222
223 fn write_slices<const N: usize>(&mut self, slices: [&[u8]; N]) -> Result<(), Self::Error> {
224 self.0.write_slices(slices)
225 }
226}
227
228const _: () = {
229 assert!(mem::size_of::<OwnedIter<'static>>() == mem::size_of::<&[Owned]>());
230 assert!(
231 mem::size_of::<ValueWriter<'static>>() == mem::size_of::<write::Staged<'static, usize>>()
232 );
233};
234
235struct Space<'a> {
236 stage: write::Staged<'a, usize>,
237 prefix: [u8; Prefix::LEN],
238 vlen: usize,
239}
240
241impl<'a> Space<'a> {
242 fn new(
243 bytes: &'a mut Vec<u8>,
244 name: usize,
245 value: usize,
246 indexing: crate::field::Indexing,
247 ) -> Result<Self, Error> {
248 let nwire = packed_len(name)?;
249 let vwire = packed_len(value)?;
250 let added = Prefix::LEN + nwire as usize + vwire as usize;
251 let stage = write::Staged::<usize>::try_reserve(bytes, added).map_err(Error::Reserve)?;
252 Ok(Self {
253 stage,
254 prefix: Prefix::new(nwire, vwire, indexing).to_bytes(),
255 vlen: value,
256 })
257 }
258
259 fn generated<F>(self, name: &[u8], encode: F) -> Result<write::Staged<'a, usize>, Error>
260 where
261 F: FnOnce(&mut ValueWriter<'_>) -> Result<(), consume::Error>,
262 {
263 let expected = self.vlen;
264 let prefix = self.stage.capacity() - expected;
265 let mut writer = ValueWriter(self.stage);
266 writer
267 .write_slices([&self.prefix, name])
268 .map_err(Error::Write)?;
269 encode(&mut writer).map_err(Error::Write)?;
270 writer.0.try_complete().map_err(|error| {
271 let (_, actual) = error.into_parts();
272 Error::ValueLengthMismatch {
273 expected,
274 actual: actual - prefix,
275 }
276 })
277 }
278}