107

I have to convert the PathBuf variable to a String to feed my function. My code is like this:

let cwd = env::current_dir().unwrap();
let my_str: String = cwd.as_os_str().to_str().unwrap().to_string();
println!("{:?}", my_str);

it works but is awful with the cwd.as_os_str…. Do you have a more convenient method or any suggestions on how to handle it?

Alex W
  • 37,233
  • 13
  • 109
  • 109
xiaoai
  • 1,181
  • 2
  • 7
  • 5

4 Answers4

89

As mcarton has already said it is not so simple as not all paths are UTF-8 encoded. But you can use:

p.into_os_string().into_string()

In order to have a fine control of it utilize ? to send error to upper level or simply ignore it by calling unwrap():

let my_str = cwd.into_os_string().into_string().unwrap();

A nice thing about into_string() is that the error wrap the original OsString value.

John Smith
  • 835
  • 1
  • 7
  • 19
Michele d'Amico
  • 22,111
  • 8
  • 69
  • 76
37

It is not easy on purpose: String are UTF-8 encoded, but PathBuf might not be (eg. on Windows). So the conversion might fail.

There are also to_str and to_string_lossy methods for convenience. The former returns an Option<&str> to indicate possible failure and the later will always succeed but will replace non-UTF-8 characters with U+FFFD REPLACEMENT CHARACTER (which is why it returns Cow<str>: if the path is already valid UTF-8, it will return a reference to the inner buffer but if some characters are to be replaced, it will allocate a new String for that; in both case you can then use into_owned if you really need a String).

mcarton
  • 27,633
  • 5
  • 85
  • 95
  • 1
    Could you add a short explanation about `Cow` and the hint to use `into_owned()`? Or may I edit your answer to add it? – Lukas Kalbertodt May 23 '16 at 12:10
  • 2
    Thank you very much. @lukas kalbertodt, for the usage of Cow, you can refer to this blog: http://hermanradtke.com/2015/05/29/creating-a-rust-function-that-returns-string-or-str.html – xiaoai May 24 '16 at 11:12
28

One way to convert PathBuf to String would be:

your_path.as_path().display().to_string();

Paras Bhattrai
  • 429
  • 5
  • 5
  • 2
    I've been using this because it is convenient. Do you know if it uses to_string_lossy() internally? Otherwise, I wonder how it does the conversion without returning any possible error? – danda Jun 03 '20 at 16:45
  • 3
    The `.as_path()` method is not necessary per the documentation: "It also implements `Deref` to `Path`, meaning that all methods on `Path` slices are available on `PathBuf` values as well." – Alex W Jan 24 '21 at 07:05
4

As @mcarton mentioned, to_string_lossy() should do the job.

let cwd = env::current_dir().unwrap();
let path: String =String::from(cwd.to_string_lossy());

rustc 1.56.1 (59eed8a2a 2021-11-01)

I am a (learning) Rust fan (years of c/c++ programmer) but man, if it makes simple thing so complicated, UTF-8 and COW.. makes people lost in the translation.

ypwang
  • 89
  • 2