I’m trying to be more disciplined about it; that would probably work in the majority of cases, and maybe even all of the ones I care about, but that’s why I’m asking!
parse the path into segments. If this is actually based on an URL, then use an URL-aware parser to get the segments out. If it is an URL, then you can split on /. If the original path is not an URL but some arbitrary platform-specific path format, then this is more complicated.
construct a platform-specific path out of those segments. This is where you would std::path::MAIN_SEPARATOR to join the segments back together.
You need to be careful about encoding. Each path component has to be urlencoded: "foo bar" -> foo%20bar. Technically, there's no standard encoding for paths in the URLs. On Unix, it usually needs to be whatever the server expects, which tends to be any bytes the filesystem has stored.
let mut path_with_forward_slash = OsString::new();
for (i, component) in path.components().enumerate() {
if i > 0 {
path_with_forward_slash.push("/");
}
path_with_forward_slash.push(component);
}
// if we have a non-utf8 path here, it will fail, but that's not realistically going to happen
let bytes = path_with_forward_slash.to_str().expect("found a non-UTF-8 path").as_bytes();
let encoded_filename = percent_encode(bytes, DEFAULT_ENCODE_SET);
println!("{}", encoded_filename.to_string());