I am trying to store file paths in a file. These paths arrive as a PathBuf
value. Unfortunately PathBuf
cannot be converted directly to a byte slice. It can be converted to an OsString
, but the problem of being able to write said string to a file still exists.
There is the into_encoded_bytes() method, and its corresponding unsafe from_encoded_bytes_unchecked() method, but the safety instructions on that indicate that it may only be used with data encoded by the same rust version on the same platform. Not useful if I want to move my data file between platforms, or update the program that produces it.
The from_encoded_bytes_unchecked() method also links to module level discussion of conversions. This describes separate methods of encoding on Windows, Unix, and "Other platforms", but the section titled "All platforms" just points back to the into_encoded_bytes() and from_encoded_bytes_unchecked() methods, which do not allow for reading the data on a different platform than it was written on.
Is there any way to serialize an arbitrary file path which will allow that serialized path to be used in a cross platform manner? Other than attempting to convert to a String
, and refusing to work if it's not valid UTF-8?
If you need the paths to all share the same format on all platforms (and always be supportable on all platforms; see why Path can't always just turn directly into a String), I think you may need to call Path::components on the paths and then write them with your desired formatting manually. Basically it would be a very simple microparser. You could try using write!(file, "{}", path.display())
(this will give you the same result as converting to String lossily).
The issue as I understand lies exactly in that bit about encoded bytes not being portable. You say that you want to consider switching platforms but not all Windows paths are valid Linux/MacOS paths and vica versa. Raw paths are not cross-platform things and either need to be formatted or manually parsed to and from other platforms for lossless encoding (all the meaning is included) or you could do the more common approach of just dumbing down the paths for debugging purposes (to_string_lossy) or reject paths that cannot be encoded (into_string).