codex_percent/encode/
fixed.rs1use super::*;
4use crate::{EncoderError, FixedEncoder as Encoder};
5
6impl<'i, const S: usize> Encoder<'i, S> {
7 pub fn init() -> Self {
9 let cur: [u8; S] = [0; S];
10 Self {
11 cur_block: cur,
12 cur_raw: None,
13 }
14 }
15 pub fn cur_block(&self) -> &[u8; S] {
17 &self.cur_block
18 }
19 pub fn cur_raw(&self) -> Option<&str> {
21 self.cur_raw
22 }
23 pub fn encode(&mut self, raw: &'i str) -> Result<usize, EncoderError> {
27 let mut cur_i = 0;
28 self.cur_raw = Some(raw);
29
30 let mut lexer = EncodeToken::lexer(raw);
31 while let Some(token) = lexer.next() {
32 match token {
33 Ok(EncodeToken::Unreserved(alphanum)) => {
34 let needed = alphanum.as_bytes().len();
35 let fill_to = cur_i + needed;
36 self.cur_block[cur_i..fill_to].copy_from_slice(&alphanum.as_bytes()[0..needed]);
37 cur_i += needed;
38 }
39 Ok(EncodeToken::NotUnreserved(notalphanum)) => {
40 let mut bytes = notalphanum.bytes();
41 while let Some(a) = bytes.next() {
42 let (higher, lower) = byte2hex(a, &HEX_CHARS_UPPER);
43 let needed = 3;
44 self.cur_block[cur_i] = 37;
45 self.cur_block[cur_i + 1] = higher;
46 self.cur_block[cur_i + 2] = lower;
47 cur_i = cur_i + needed;
48 }
49 }
50 _ => {
51 return Err(EncoderError::BorkedExperimental(lexer.span().start));
52 }
53 }
54 }
55 Ok(cur_i)
56 }
57}
58
59#[cfg(test)]
60mod test {
61 use super::*;
62
63 #[test]
64 fn f_10_direct_copy() {
65 let s = "1234567890";
66
67 let mut e = Encoder::<10>::init();
68 let f = e.encode(s).unwrap();
69
70 assert_eq!(f, 10);
71 assert_eq!(e.cur_block, [49, 50, 51, 52, 53, 54, 55, 56, 57, 48]);
72 }
73 #[test]
74 fn f_10_poop() {
75 let s = "💩";
76
77 let mut e = Encoder::<12>::init();
78 let res = e.encode(s).unwrap();
79
80 assert_eq!(res, 12);
81 let t = core::str::from_utf8(e.cur_block.as_slice());
82
83 assert_eq!(t, Ok("%F0%9F%92%A9"));
84 }
85 #[test]
86 fn f_10_spaces() {
87 let s = " ";
88
89 let mut e = Encoder::<30>::init();
90 let f = e.encode(s).unwrap();
91
92 assert_eq!(f, 30);
93
94 let t = core::str::from_utf8(e.cur_block.as_slice());
95 assert_eq!(t, Ok("%20%20%20%20%20%20%20%20%20%20"));
96
97 assert_eq!(
98 e.cur_block,
99 [
100 37, 50, 48, 37, 50, 48, 37, 50, 48, 37, 50, 48, 37, 50, 48, 37, 50, 48, 37, 50, 48,
101 37, 50, 48, 37, 50, 48, 37, 50, 48
102 ]
103 );
104 }
105}