codex_percent/decode/
vec.rs

1//! Decode impl - Vec output
2
3use super::*;
4use crate::{DecoderError, VecDecoder as Decoder};
5
6#[cfg(all(feature = "alloc", not(feature = "std")))]
7use alloc::vec::*;
8
9impl Decoder {
10    /// Decode and append result into the provided &mut Vec
11    /// Result Ok() Provides the written bytes
12    pub fn decode(raw: &str, vin: &mut Vec<u8>) -> Result<usize, DecoderError> {
13        let mut cur_i = 0;
14
15        let mut lexer = DecodeToken::lexer(raw);
16        while let Some(token) = lexer.next() {
17            match token {
18                Ok(DecodeToken::MaybePercent2Hex(pairs)) => {
19                    let mut chunks = pairs.as_bytes().chunks(3);
20                    while let Some(block) = chunks.next() {
21                        let pair: [u8; 2] = [block[1], block[2]];
22                        let byte_out = hex2byte(pair)?;
23                        vin.push(byte_out);
24                        cur_i = cur_i + 1;
25                    }
26                }
27                Ok(DecodeToken::EverythingElse(alphanum)) => {
28                    let needed = alphanum.as_bytes().len();
29                    vin.extend_from_slice(&alphanum.as_bytes()[0..needed]);
30                    cur_i += needed;
31                }
32                _ => {
33                    return Err(DecoderError::BorkedExperimental(lexer.span().start));
34                }
35            }
36        }
37        Ok(cur_i)
38    }
39}
40
41#[cfg(test)]
42mod test {
43    use super::*;
44
45    #[test]
46    fn f_10_direct_copy() {
47        let s = "1234567890";
48        let expected: Vec<u8> = vec![49, 50, 51, 52, 53, 54, 55, 56, 57, 48];
49
50        let mut d: Vec<u8> = Vec::new();
51        let c = Decoder::decode(s, &mut d).unwrap();
52        let utf8 = core::str::from_utf8(&d).unwrap();
53
54        assert_eq!(c, 10);
55        assert_eq!(d, expected);
56        assert_eq!(utf8, s);
57    }
58
59    #[test]
60    fn f_10_poop() {
61        let poop_str = "%F0%9F%92%A9";
62        let expected: Vec<u8> = vec![240, 159, 146, 169];
63        let expected_utf8 = "💩";
64
65        let mut d: Vec<u8> = Vec::new();
66        let c = Decoder::decode(poop_str, &mut d).unwrap();
67        let utf8 = core::str::from_utf8(&d).unwrap();
68
69        assert_eq!(c, 4);
70        assert_eq!(d, expected);
71        assert_eq!(expected_utf8, utf8);
72    }
73
74    #[test]
75    fn f_10_spaces() {
76        let poop_str = "%20%20%20%20%20%20%20%20%20%20";
77        let expected: Vec<u8> = vec![32, 32, 32, 32, 32, 32, 32, 32, 32, 32];
78        let expected_utf8 = "          ";
79
80        let mut d: Vec<u8> = Vec::new();
81        let c = Decoder::decode(poop_str, &mut d).unwrap();
82        let utf8 = core::str::from_utf8(&d).unwrap();
83
84        assert_eq!(c, 10);
85        assert_eq!(d, expected);
86        assert_eq!(expected_utf8, utf8);
87    }
88
89    #[test]
90    fn f_10_mixmash() {
91        let poop_str = "%20 %20 %20";
92        let expected: Vec<u8> = vec![32, 32, 32, 32, 32];
93        let expected_utf8 = "     ";
94
95        let mut d: Vec<u8> = Vec::new();
96        let c = Decoder::decode(poop_str, &mut d).unwrap();
97        let utf8 = core::str::from_utf8(&d).unwrap();
98
99        assert_eq!(c, 5);
100        assert_eq!(d, expected);
101        assert_eq!(expected_utf8, utf8);
102    }
103}