codex_percent/encode/
vec.rs

1//! Encode impl - Vec allocated output
2
3use super::*;
4use crate::{EncoderError, VecEncoder as Encoder};
5
6#[cfg(all(feature = "alloc", not(feature = "std")))]
7use alloc::vec::*;
8
9impl Encoder {
10    /// Encode and append result into the provided &mut Vec
11    /// Result Ok() Provides the written bytes
12    pub fn encode(raw: &str, vin: &mut Vec<u8>) -> Result<usize, EncoderError> {
13        let mut cur_i = 0;
14
15        let mut lexer = EncodeToken::lexer(raw);
16        while let Some(token) = lexer.next() {
17            match token {
18                Ok(EncodeToken::Unreserved(alphanum)) => {
19                    let needed = alphanum.as_bytes().len();
20                    vin.extend_from_slice(&alphanum.as_bytes()[0..needed]);
21                    cur_i += needed;
22                }
23                Ok(EncodeToken::NotUnreserved(notalphanum)) => {
24                    let mut bytes = notalphanum.bytes();
25                    while let Some(a) = bytes.next() {
26                        let (higher, lower) = byte2hex(a, &HEX_CHARS_UPPER);
27                        let needed = 3;
28                        vin.push(37);
29                        vin.push(higher);
30                        vin.push(lower);
31                        cur_i = cur_i + needed;
32                    }
33                }
34                _ => {
35                    return Err(EncoderError::BorkedExperimental(lexer.span().start));
36                }
37            }
38        }
39        Ok(cur_i)
40    }
41}
42
43#[cfg(test)]
44mod test {
45    use super::*;
46
47    #[test]
48    fn f_10_direct_copy_no_cap() {
49        let s = "1234567890";
50        let mut v: Vec<u8> = Vec::new();
51
52        let f = Encoder::encode(s, &mut v).unwrap();
53
54        assert_eq!(f, 10);
55        assert_eq!(v, [49, 50, 51, 52, 53, 54, 55, 56, 57, 48]);
56    }
57    #[test]
58    fn f_10_direct_copy_10_cap() {
59        let s = "1234567890";
60
61        let mut v: Vec<u8> = Vec::with_capacity(10);
62        let f = Encoder::encode(s, &mut v).unwrap();
63
64        assert_eq!(f, 10);
65        assert_eq!(v, [49, 50, 51, 52, 53, 54, 55, 56, 57, 48]);
66    }
67    #[test]
68    fn f_10_poop() {
69        let s = "💩";
70
71        let mut v: Vec<u8> = Vec::new();
72        let f = Encoder::encode(s, &mut v).unwrap();
73
74        assert_eq!(f, 12);
75        let t = core::str::from_utf8(v.as_slice());
76
77        assert_eq!(t, Ok("%F0%9F%92%A9"));
78    }
79    #[test]
80    fn f_10_spaces() {
81        let s = "          ";
82
83        let mut v: Vec<u8> = Vec::new();
84        let f = Encoder::encode(s, &mut v).unwrap();
85
86        assert_eq!(f, 30);
87
88        let t = core::str::from_utf8(v.as_slice());
89        assert_eq!(t, Ok("%20%20%20%20%20%20%20%20%20%20"));
90
91        assert_eq!(
92            v,
93            [
94                37, 50, 48, 37, 50, 48, 37, 50, 48, 37, 50, 48, 37, 50, 48, 37, 50, 48, 37, 50, 48,
95                37, 50, 48, 37, 50, 48, 37, 50, 48
96            ]
97        );
98    }
99}