Question
How could I print a path in Rust?
I tried the following in order to print the current working directory:
use std::os;
fn main() {
let p = os::getcwd();
println!("{}", p);
}
But rustc
returns with the following error:
[wei2912@localhost rust-basics]$ rustc ls.rs
ls.rs:5:17: 5:18 error: failed to find an implementation of trait core::fmt::Show for std::path::posix::Path
ls.rs:5 println!("{}", p);
^
note: in expansion of format_args!
<std macros>:2:23: 2:77 note: expansion site
<std macros>:1:1: 3:2 note: in expansion of println!
ls.rs:5:2: 5:20 note: expansion site
Solution
As you discovered, the "correct" way to print a Path
is via the .display
method, which returns a type that implements Display
.
There is a reason Path
does not implement Display
itself: formatting a path to a string is a lossy operation. Not all operating systems store paths compatible with UTF-8 and the formatting routines are implicitly all dealing with UTF-8 data only.
As an example, on my Linux system a single byte with value 255 is a perfectly valid filename, but this is not a valid byte in UTF-8. If you try to print that Path
to a string, you have to handle the invalid data somehow: .display
will replace invalid UTF-8 byte sequences with the replacement character U+FFFD, but this operation cannot be reversed.
In summary, Path
s should rarely be handled as if they were strings, and so they don't implement Display
to encourage that.
OTHER TIPS
The following will print out the full path:
println!("{}", p.display());
Refer to Path::display
for more details.
As a related tangent, I've written a library for when you "just want it in UTF-8" stfu8.
This uses escape characters (i.e. \x00
) to format any nearly-UTF-8 sequence the way a developer might expect.