Converting Rust String to and From

Rust &str and String is different in a sense that str is static, owned and fix sized while String can be dynamically allocated once and be converted to mutable to be appended. Most of the time you’ll be working with String on Rust when re-allocating and moving values between structs.
There are times you may need to convert dynamic string to char bytes and static string. Here are ways to do it:
From &str
&str -> Stringhas many equally valid methods:String::from(st),st.to_string(),st.to_owned().- But I suggest you stick with one of them within a single project. The major advantage of
String::fromis that you can use it as an argument to amapmethod. So instead ofx.map(|s| String::from(s))you can often usex.map(String::from).
- But I suggest you stick with one of them within a single project. The major advantage of
&str->&[u8]is done byst.as_bytes()&str->Vec<u8>is a combination of&str -> &[u8] -> Vec<u8>, i.e.st.as_bytes().to_vec()orst.as_bytes().to_owned()
From String
String -> &strshould just be&swhere coercion is available ors.as_str()where it is not.String -> &[u8]is the same as&str -> &[u8]:s.as_bytes()String -> Vec<u8>has a custom method:s.into_bytes()
From &[u8]
&[u8] -> Vec<u8>is done byu.to_owned()oru.to_vec(). They do the same thing, butto_vechas the slight advantage of being unambiguous about the type it returns.&[u8] -> &strdoesn’t actually exist, that would be&[u8] -> Result<&str, Error>, provided viastr::from_utf8(u)str::from_utf8(u).unwrap()works, but you should prefer better error handling (see Error handling – The Result type).
&[u8] -> Stringis the combination of&[u8] -> Result<&str, Error> -> Result<String, Error>String::from_utf8(u).unwrap()works, but prefer better error handling (see Error handling – The Result type and alsoResult::map.
From Vec<u8>
Vec<u8> -> &[u8]should be just&vwhere coercion is available, oras_slicewhere it’s not.Vec<u8> -> &stris the same asVec<u8> -> &[u8] -> Result<&str, Error>i.e.str::from_utf8(&v)str::from_utf8(&v).unwrap()works, but prefer better error handling (see Error handling – The Result type)
Vec<u8> -> Stringdoesn’t actually exist, that would beVec<u8> -> Result<String, Error>viaString::from_utf8(v)String::from_utf8(v).unwrap()works, but prefer better error handling (see Error handling – The Result type).
Coercion is available whenever the target is not generic but explicitly typed as &str or &[u8], respectively. The Rustonomicon has a chapter on coercions with more details about coercion sites.
tl;dr
&str -> String | String::from(s) or s.to_string() or s.to_owned()
&str -> &[u8] | s.as_bytes()
&str -> Vec<u8> | s.as_bytes().to_vec() or s.as_bytes().to_owned()
String -> &str | &s if possible* else s.as_str()
String -> &[u8] | s.as_bytes()
String -> Vec<u8> | s.into_bytes()
&[u8] -> &str | s.to_vec() or s.to_owned()
&[u8] -> String | std::str::from_utf8(s).unwrap(), but don't**
&[u8] -> Vec<u8> | String::from_utf8(s).unwrap(), but don't**
Vec<u8> -> &str | &s if possible* else s.as_slice()
Vec<u8> -> String | std::str::from_utf8(&s).unwrap(), but don't**
Vec<u8> -> &[u8] | String::from_utf8(s).unwrap(), but don't**
* target should have explicit type (i.e., checker can't infer that)
** handle the error properly instead