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
Was it helpful?

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, Paths 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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top