chipsenkbeil / typed-path

Provides typed variants of Path and PathBuf for Unix and Windows
39 stars 7 forks source link

Interopting with `std::path::Path` #28

Open jabuwu opened 4 months ago

jabuwu commented 4 months ago

Hey there, excellent library. I'm wondering if there is a recommended way to convert back and forth between the std::path::Path and std::path::PathBuf types.

It's nice to store types as Utf8NativePath, because that has an AsRef<std::path::Path>. That type can easily be passed into other libraries that expect the std path types.

However, it seems quite cumbersome to create that from an std path:

let native_path = Utf8NativePath::from_bytes_path(NativePath::new(
    std_path.as_os_str().as_encoded_bytes(),
))
.expect("Path did not contain valid UTF-8 characters");

It seems to me that NativePath should have a From<std::path::Path>, since from_bytes_path is is infallable, and Utf8NativePath should have a fallable TryFrom<std::path::Path> with Utf8Error.

The library does an amazing job documenting and interopting with itself, but much of the Rust ecosystem uses std path, so I find this library hard to work with practically. Perhaps I missed something obvious?

Thanks for your time!

chipsenkbeil commented 4 months ago

Hey there! Thanks for reaching out :)

I took a look and the as_encoded_bytes is a newer function introduced in Rust 1.74.0. Before then, there was not a cross-platform, safe way to convert to a byte slice IIRC. Conversions weren't seamless because of the inability to convert in one direction, limited by Windows' wide word string implementation.

Been awhile since I took a look, so maybe there's a cleaner way to do this now. :)

jabuwu commented 4 months ago

Oh, I see. Indeed, as_encoded_bytes seems to do the trick. The code I posted works on Windows and Mac, according to my testing.

I'm happy to make a PR for this if I find the time. Wanted to make sure I wasn't missing something.

chipsenkbeil commented 4 months ago

One thing to keep in mind is that as_encoded_bytes exports a platform-dependent byte slice. If you want to share your path across machines over the network, it isn't a good idea to use it.

For my personal use case, I leverage this library specifically to have a platform-agnostic way to share paths over a network; so, if this library ends up leveraging the conversion to-and-from encoded bytes, there will need to be a disclaimer since it would cause issues for those like me that didn't realize this constraint.