use percent_encoding::{AsciiSet, CONTROLS, utf8_percent_encode};
const PATH_SEGMENT: &AsciiSet = &CONTROLS
.add(b' ')
.add(b'"')
.add(b'#')
.add(b'%')
.add(b'/')
.add(b'<')
.add(b'>')
.add(b'?')
.add(b'\\')
.add(b'`')
.add(b'{')
.add(b'}');
pub fn encode_path_segment(s: &str) -> String {
utf8_percent_encode(s, PATH_SEGMENT).to_string()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn encodes_slash_question_hash() {
assert_eq!(encode_path_segment("a/b"), "a%2Fb");
assert_eq!(encode_path_segment("a?b"), "a%3Fb");
assert_eq!(encode_path_segment("a#b"), "a%23b");
}
#[test]
fn leaves_uuid_untouched() {
let uuid = "8f3b2d1c-4a5e-4f6a-9b8c-1d2e3f4a5b6c";
assert_eq!(encode_path_segment(uuid), uuid);
}
#[test]
fn encodes_space_and_unicode() {
assert_eq!(encode_path_segment("hello world"), "hello%20world");
assert_eq!(encode_path_segment("café"), "caf%C3%A9");
}
#[test]
fn encodes_path_traversal() {
assert_eq!(encode_path_segment(".."), ".."); assert_eq!(encode_path_segment("../etc/passwd"), "..%2Fetc%2Fpasswd");
}
}