1pub use simoom_hpack::huffman::{encode, encoded_len};
6
7#[allow(clippy::result_unit_err)]
10pub fn decode(data: &[u8], out: &mut Vec<u8>) -> Result<(), ()> {
11 simoom_hpack::huffman::decode(data, out).map_err(|_| ())
12}
13
14#[cfg(test)]
15mod tests {
16 use super::*;
17
18 fn hex(s: &str) -> Vec<u8> {
19 let s: String = s.chars().filter(|c| !c.is_whitespace()).collect();
20 (0..s.len()).step_by(2).map(|i| u8::from_str_radix(&s[i..i + 2], 16).unwrap()).collect()
21 }
22
23 fn dec(d: &[u8]) -> Result<Vec<u8>, ()> {
24 let mut out = Vec::new();
25 decode(d, &mut out).map(|_| out)
26 }
27
28 #[test]
29 fn rfc7541_c4_vectors() {
30 let mut out = Vec::new();
31 encode(b"www.example.com", &mut out);
32 assert_eq!(out, hex("f1e3 c2e5 f23a 6ba0 ab90 f4ff"));
33 assert_eq!(dec(&out).unwrap(), b"www.example.com");
34 assert_eq!(encoded_len(b"www.example.com"), 12);
35 assert_eq!(dec(&hex("a8eb 1064 9cbf")).unwrap(), b"no-cache");
36 assert_eq!(dec(&hex("25a8 49e9 5ba9 7d7f")).unwrap(), b"custom-key");
37 assert_eq!(dec(&hex("25a8 49e9 5bb8 e8b4 bf")).unwrap(), b"custom-value");
38 assert_eq!(dec(&hex("6402")).unwrap(), b"302");
39 assert_eq!(dec(&hex("aec3 771a 4b")).unwrap(), b"private");
40 assert_eq!(
41 dec(&hex("d07a be94 1054 d444 a820 0595 040b 8166 e082 a62d 1bff")).unwrap(),
42 b"Mon, 21 Oct 2013 20:13:21 GMT"
43 );
44 assert_eq!(dec(&hex("9d29 ad17 1863 c78f 0b97 c8e9 ae82 ae43 d3")).unwrap(), b"https://www.example.com");
45 }
46
47 #[test]
48 fn all_bytes_round_trip() {
49 let data: Vec<u8> = (0..=255u8).chain((0..=255u8).rev()).collect();
50 let mut out = Vec::new();
51 encode(&data, &mut out);
52 assert_eq!(out.len(), encoded_len(&data));
53 assert_eq!(dec(&out).unwrap(), data);
54 assert_eq!(dec(&[]).unwrap(), b"");
55 }
56
57 #[test]
58 fn invalid_padding_and_eos() {
59 assert!(dec(&[0b0001_1000]).is_err());
60 assert_eq!(dec(&[0b0001_1111]).unwrap(), b"a");
61 assert!(dec(&[0b0001_1111, 0xff]).is_err());
62 assert!(dec(&[0xff, 0xff, 0xff, 0xff]).is_err());
64 }
65}