pub(crate) fn percent_encode(message: &str) -> String { let mut encoded = String::with_capacity(message.len() + 16); message.as_bytes().iter().for_each(|b| { match b { b if (b >= &b'a' && b <= &b'z') || (b >= &b'A' && b <= &b'Z') || (b >= &b'0' && b <= &b'9') => encoded.push(*b as char), b'~' | b'_' | b'-' | b'.' => encoded.push(*b as char), _ => encoded.push_str(&format!("%{:X}", b)), } }); encoded } #[inline] pub(crate) fn join_slices(part1: &[u8], part2: &[u8]) -> Vec { let mut joined = part1.to_vec(); joined.extend_from_slice(part2); joined } #[test] fn test_percent_encode() { assert_eq!("0123456789", percent_encode("0123456789")); assert_eq!("abcdefghijklmnopqrstuvwxyz", percent_encode("abcdefghijklmnopqrstuvwxyz")); assert_eq!("ABCDEFGHIJKLMNOPQRSTUVWXYZ", percent_encode("ABCDEFGHIJKLMNOPQRSTUVWXYZ")); assert_eq!("Hello%20World%21", percent_encode("Hello World!")); assert_eq!("~%21%40%23%24%25%5E%26%2A%28%29_%2B-%3D", percent_encode("~!@#$%^&*()_+-=")); assert_eq!("%E8%BF%99%E6%98%AF%E4%B8%80%E4%B8%AA%E6%B5%8B%E8%AF%95", percent_encode("这是一个测试")); assert_eq!("%F0%9F%98%84", percent_encode("😄")); assert_eq!("%2C.%2F%3C%3E%3F%3B%27%3A%22%5B%5D%5C%7B%7D%7C", percent_encode(",./<>?;':\"[]\\{}|")); assert_eq!("%21%27%28%29%2A-._~", percent_encode("!'()*-._~")); assert_eq!("%21%23%24%26%27%28%29%2A%2B%2C-.%2F%3A%3B%3D%3F%40_~", percent_encode("!#$&'()*+,-./:;=?@_~")); } #[test] fn test_join_slices() { assert_eq!(&b"Hello World"[..], &join_slices(b"Hello", b" World")[..]) }