135

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?

0

5 Answers 5

109

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.

Sign up to request clarification or add additional context in comments.

Comments

47

One way to convert PathBuf to String would be:

your_path.display().to_string()

2 Comments

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 As of time of writing, the implementation is from here, which looks pretty similar to to_string_lossy(). It does write U+FFFD where utf8 decoding fails.
43

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).

2 Comments

Could you add a short explanation about Cow and the hint to use into_owned()? Or may I edit your answer to add it?
Thank you very much. @lukas kalbertodt, for the usage of Cow, you can refer to this blog: hermanradtke.com/2015/05/29/…
8

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.

Comments

3

The shortest solution, which also takes Unicode characters into account, as necessary for Windows paths:

let my_str: String = cwd.display().to_string();

Playground

5 Comments

This is just a repetition of Paras Bhattrais answer. Please only add an answer if you have something new to add.
@cafce25 When I wrote my solution, this solution didn't exist yet. Other solutions at least included the unnecessary .as_path() conversion, unlike mine.
@cafce25 Despite the many changes, the solution is still not correct. cwd is a PathBuf and it is still not necessary to convert it first into a path your_path as @Paras assumes.
@cafce25 It's not about the names it's about the types: you can directly convert std::path::PathBuf into a string without the detour over converting the std::path::PathBuf first into a std::path::Path and then into a string.
answered Apr 11, 2020 at 13:25: your_path.as_path().display().to_string(); answered: Sep: 17, 2020 at 14:37: cwd.display().to_string();

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.