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 {
86 bytes: Vec<u8>,
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 ValueLengthMismatch {
97 expected: usize,
98 actual: usize,
99 },
100}
101
102fn packed_len(len: usize) -> Result<u32, usize> {
103 if len > u32::MAX as usize {
104 return Err(len);
105 }
106 Ok(len as u32)
107}
108
109impl From<usize> for Error {
110 fn from(len: usize) -> Self {
111 Self::ComponentTooLarge { len }
112 }
113}
114
115impl metadata::Metadata for Fields {
116 type Iter<'a> = Iter<'a>;
117
118 fn fields(&self) -> Self::Iter<'_> {
119 Iter::new(self.bytes.as_ref())
120 }
121}
122
123impl Fields {
124 pub const fn new() -> Self {
125 Self { bytes: Vec::new() }
126 }
127
128 pub fn try_with(capacity: usize) -> Result<Self, Error> {
129 Ok(Self {
130 bytes: Vec::try_new(capacity).map_err(Error::Reserve)?,
131 })
132 }
133
134 pub fn push(&mut self, name: &[u8], value: &[u8]) -> Result<(), Error> {
135 self.push_entry(Entry::new(name, value))
136 }
137
138 pub fn push_entry(&mut self, field: Entry<'_>) -> Result<(), Error> {
139 self.push_with(
140 field.name,
141 field.value.len(),
142 field.indexing,
143 |writer| writer.write_slice(field.value),
144 )
145 }
146
147 pub fn push_encoded<F>(&mut self, name: &[u8], vlen: usize, encode: F) -> Result<(), Error>
151 where
152 F: FnOnce(&mut ValueWriter<'_>) -> Result<(), consume::Error>,
153 {
154 self.push_with(name, vlen, crate::field::Indexing::Allowed, encode)
155 }
156
157 pub fn push_with<F>(
159 &mut self,
160 name: &[u8],
161 vlen: usize,
162 indexing: crate::field::Indexing,
163 encode: F,
164 ) -> Result<(), Error>
165 where
166 F: FnOnce(&mut ValueWriter<'_>) -> Result<(), consume::Error>,
167 {
168 Space::new(&mut self.bytes, name.len(), vlen, indexing)?
169 .generated(name, encode)?
170 .commit();
171 Ok(())
172 }
173
174 pub fn iter(&self) -> Iter<'_> {
175 Iter::new(self.bytes.as_ref())
176 }
177
178 pub fn get(&self, name: &[u8]) -> Option<&[u8]> {
179 self.iter()
180 .find(|field| field.name == name)
181 .map(|field| field.value)
182 }
183
184 pub fn as_bytes(&self) -> &[u8] {
185 self.bytes.as_ref()
186 }
187
188 pub fn ranges(&self) -> RangeIter<'_> {
189 RangeIter::new(self.bytes.as_ref(), 0)
190 }
191}
192
193impl Default for Fields {
194 fn default() -> Self {
195 Self::new()
196 }
197}
198
199#[repr(transparent)]
201pub struct ValueWriter<'a>(write::Staged<'a, usize>);
202
203impl write::Sink for ValueWriter<'_> {
204 type Error = consume::Error;
205
206 fn write_slice(&mut self, bytes: &[u8]) -> Result<(), Self::Error> {
207 self.0.write_slice(bytes)
208 }
209
210 fn write_slices<const N: usize>(&mut self, slices: [&[u8]; N]) -> Result<(), Self::Error> {
211 self.0.write_slices(slices)
212 }
213}
214
215const _: () = {
216 assert!(mem::size_of::<OwnedIter<'static>>() == mem::size_of::<&[Owned]>());
217 assert!(
218 mem::size_of::<ValueWriter<'static>>() == mem::size_of::<write::Staged<'static, usize>>()
219 );
220};
221
222struct Space<'a> {
223 stage: write::Staged<'a, usize>,
224 prefix: [u8; Prefix::LEN],
225 vlen: usize,
226}
227
228impl<'a> Space<'a> {
229 fn new(
230 bytes: &'a mut Vec<u8>,
231 name: usize,
232 value: usize,
233 indexing: crate::field::Indexing,
234 ) -> Result<Self, Error> {
235 let nwire = packed_len(name)?;
236 let vwire = packed_len(value)?;
237 let added = Prefix::LEN + nwire as usize + vwire as usize;
238 let stage = write::Staged::<usize>::try_reserve(bytes, added).map_err(Error::Reserve)?;
239 Ok(Self {
240 stage,
241 prefix: Prefix::new(nwire, vwire, indexing).to_bytes(),
242 vlen: value,
243 })
244 }
245
246 fn generated<F>(self, name: &[u8], encode: F) -> Result<write::Staged<'a, usize>, Error>
247 where
248 F: FnOnce(&mut ValueWriter<'_>) -> Result<(), consume::Error>,
249 {
250 let expected = self.vlen;
251 let prefix = self.stage.capacity() - expected;
252 let mut writer = ValueWriter(self.stage);
253 writer
254 .write_slices([&self.prefix, name])
255 .map_err(Error::Write)?;
256 encode(&mut writer).map_err(Error::Write)?;
257 writer.0.try_complete().map_err(|error| {
258 let (_, actual) = error.into_parts();
259 Error::ValueLengthMismatch {
260 expected,
261 actual: actual - prefix,
262 }
263 })
264 }
265}