mark
1
I am using String::from_utf8 in a function that I want to return Result using error-chain. However, this doesn't work:
pub mod errors {
error_chain!{
foreign_links {
Io(::std::io::Error);
Utf8(::std::string::FromUtf8Error); // error: expected struct `errors::Error`, found struct `std::string::FromUtf8Error
}
}
}
The first one, Io is copied from the docs & works fine.
Can you show the function where you’re trying to use it?
mark
3
I can only show some bits:
Here's part of the caller:
fn get_data(which: &str, prefix: &str, what: &str) -> Result<KeyValues> {
let output = Command::new("wmic").arg(&which).arg("get").arg(&what)
.arg("/format:list").output()?;
let text = string_for_bytes(output.stdout)?;
...
And here's the function that could produce the error:
fn string_for_bytes(bytes: Vec<u8>) -> Result<String> {
String::from_utf8(bytes.iter() // Effectively deletes non-ASCII chars
.map(|b| if *b > 0x7F { b' ' } else { *b })
.collect())
}
Thanks.
You need to trigger an Into
conversion. A simple way is to do this:
fn string_for_bytes(bytes: Vec<u8>) -> Result<String> {
Ok(String::from_utf8(
bytes
.iter()
.map(|b| if *b > 0x7F { b' ' } else { *b })
.collect(),
)?)
}
Or you can do:
fn string_for_bytes(bytes: Vec<u8>) -> errors::Result<String> {
String::from_utf8(
bytes
.iter()
.map(|b| if *b > 0x7F { b' ' } else { *b })
.collect(),
).map_err(Into::into)
}
mark
5
Thanks, I used the first approach & it worked perfectly!