I am trying to wrap my head around error handling.
I have the following code:
async fn read_file_content(path: &str) -> Result<String, Error> {
let raw = tokio::fs::read(path).await?;
let content = String::from_utf8(raw)?;
Ok(content)
}
struct Error {}
impl From<std::string::FromUtf8Error> for Error {
fn from(_: std::string::FromUtf8Error) -> Error {
Error {}
}
}
impl From<std::io::Error> for Error {
fn from(_: std::io::Error) -> Error {
Error {}
}
}
The idea being that I do not care to know what failed in read_file_content
, I will only handle the case where I get an error, no matter what it is.
My hope was to return Result<String, ()>
, and use the ?
operator to neatly propagate the error up and hope that it would be correctly converted. It is not converted, hence why you can see the empty struct with the implementations for each error that I am expecting.
I tried writing:
impl<T> From<T> for Error {
fn from(_: T) -> Error {
Error {}
}
}
conflicting implementations of trait `std::convert::From<Error>` for type `Error`:
note: conflicting implementation in crate `core`:
- impl<T> std::convert::From<T> for T; // rustc(E0119)
Another attempt:
impl<T> From<T> for () {
fn from(_: T) -> () {
()
}
}
conflicting implementations of trait `std::convert::From<()>` for type `()`:
note: conflicting implementation in crate `core`:
- impl<T> std::convert::From<T> for T; // rustc(E0119)
It looks like a simple enough use case, and I am kind of surprised to be stuck on this? Am I doing something wrong here?