sark_http/field/text/percent/
raw.rs1use crate::{
2 field,
3 field::{
4 storage::encoded,
5 text::percent::{Error, Length, octet, scan},
6 },
7};
8
9pub struct Encoder<'a> {
10 text: &'a str,
11 length: Length,
12}
13
14impl<'a> Encoder<'a> {
15 pub fn new(text: &'a str) -> Result<Self, Error> {
16 Ok(Self {
17 text,
18 length: Length::measure(text.as_bytes())?,
19 })
20 }
21
22 pub const unsafe fn from_length(text: &'a str, length: Length) -> Self {
26 Self { text, length }
27 }
28
29 pub const fn length(&self) -> Length {
30 self.length
31 }
32}
33
34impl encoded::Encoded for Encoder<'_> {}
35
36impl field::Encode for Encoder<'_> {
37 fn encoded_len(&self) -> usize {
38 self.length.get()
39 }
40
41 fn try_write<E>(self, mut emit: impl FnMut(&[u8]) -> Result<(), E>) -> Result<(), E> {
42 let mut bytes = self.text.as_bytes();
43 while !bytes.is_empty() {
44 let (literal, suffix) = scan::Scan::new(bytes).plain();
45 emit(literal)?;
46 let Some((&byte, tail)) = suffix.split_first() else {
47 return Ok(());
48 };
49 emit(&octet::encode(byte))?;
50 bytes = tail;
51 }
52 Ok(())
53 }
54}
55
56const _: () = assert!(core::mem::size_of::<Encoder<'_>>() == 3 * core::mem::size_of::<usize>());