pub fn os_string_from_bytes(value: Vec<u8>) -> Result<OsString, Vec<u8>>Expand description
Rebuild an OsString from bytes the parser handed back.
This is the reverse of OsStr::as_encoded_bytes, and it is how a PathBuf field
receives a filename the operating system accepts but UTF-8 does not — /tmp/\xff stays
/tmp/\xff rather than becoming a different filename with U+FFFD in it.
Where the platform cannot hold those bytes, they are handed back in the Err — as
String::from_utf8 does — so the caller can name the value in its error without this
having to copy it for a case that is nearly never taken.
§Why this is not unsafe, and why it is not lossless everywhere
On Unix an OsString is an arbitrary byte sequence, so the conversion is total and
uses the safe OsStringExt::from_vec. Every byte survives, which is the case that
matters: non-UTF-8 filenames are ordinary there.
On Windows the encoding is WTF-8, where not every byte sequence is valid, and the only
constructor that accepts one is OsString::from_encoded_bytes_unchecked — whose
precondition this function cannot enforce. It takes a Vec<u8> from a safe caller, so
there is no way to know the bytes came from as_encoded_bytes rather than from anywhere
else, and a safe function with a precondition that can be violated is unsound however
carefully its callers behave today.
So on Windows the bytes go through UTF-8, and one that is not valid UTF-8 is refused
rather than assumed. What that gives up is a Windows argument containing an unpaired
surrogate, which is reported instead of accepted; what it buys is that this crate needs no
unsafe at all.