I've defined an errors.rs
module (shown at the end).
When I use it to raise a custom error when I wait for a child process, I get a compiler error. Here's some of the relevant code:
fn run_test(test: &Test) -> XResult<i32> {
/// elided lines
let output = child.wait_with_output().or_else(|err| {
xerror(&format!(
"Failed to run \"{}\": {}",
test.app.display(),
err
))
})?;
/// elided lines
And here's the error:
error[E0308]: mismatched types
--> src/plan/process.rs:305:9
|
305 | / xerror(&format!(
306 | | "Failed to run \"{}\": {}",
307 | | test.app.display(),
308 | | err
309 | | ))
| |__________^ expected struct `std::process::Output`, found ()
|
= note: expected type `std::result::Result<std::process::Output, _>`
found type `std::result::Result<(), errors::XError>`
My xerror
function is trying to replace the error-chain bail!
macro.
Here's my errors.rs
:
use std::error::Error;
use std::fmt;
use std::io;
use std::num;
pub type XResult<T> = Result<T, XError>;
pub fn xerror<T>(message: &str) -> XResult<()> {
Err(XError::new(&message))
}
#[derive(Debug)]
pub enum XError {
Image(image::ImageError),
Io(::std::io::Error),
Json(json::Error),
Log(log::SetLoggerError),
ParseFloat(::std::num::ParseFloatError),
ParseInt(::std::num::ParseIntError),
Rayon(rayon::ThreadPoolBuildError),
Retest(String),
}
impl Error for XError {}
impl XError {
fn new(message: &str) -> XError {
XError::Retest(message.to_string())
}
}
impl fmt::Display for XError {
fn fmt(&self, out: &mut fmt::Formatter) -> fmt::Result {
match *self {
XError::Image(ref err) => write!(out, "Image error: {}", err),
XError::Io(ref err) => write!(out, "File error: {}", err),
XError::Json(ref err) => write!(out, "JSON error: {}", err),
XError::Log(ref err) => {
write!(out, "Failed to set logger: {}", err)
}
XError::ParseFloat(ref err) => {
write!(out, "Failed to read decimal number: {}", err)
}
XError::ParseInt(ref err) => {
write!(out, "Failed to read whole number: {}", err)
}
XError::Rayon(ref err) => {
write!(out, "Failed to create thread pool: {}", err)
}
XError::Retest(ref err) => write!(out, "{}", err),
}
}
}
impl From<image::ImageError> for XError {
fn from(err: image::ImageError) -> XError {
XError::Image(err)
}
}
impl From<io::Error> for XError {
fn from(err: io::Error) -> XError {
XError::Io(err)
}
}
impl From<json::Error> for XError {
fn from(err: json::Error) -> XError {
XError::Json(err)
}
}
impl From<log::SetLoggerError> for XError {
fn from(err: log::SetLoggerError) -> XError {
XError::Log(err)
}
}
impl From<num::ParseFloatError> for XError {
fn from(err: num::ParseFloatError) -> XError {
XError::ParseFloat(err)
}
}
impl From<num::ParseIntError> for XError {
fn from(err: num::ParseIntError) -> XError {
XError::ParseInt(err)
}
}
impl From<rayon::ThreadPoolBuildError> for XError {
fn from(err: rayon::ThreadPoolBuildError) -> XError {
XError::Rayon(err)
}
}