Using Result<T, E> as a return type for multiple error types


#1

Hi,

I’m trying to write a simple function which opens a TOML file at a provided path and then returns the result. In the process of opening the file, parsing it with the toml crate and then performing my own validation on the decoded structs fields a number of different error types may be generated, including std::io::Error, toml errors and my own for validation. I’m using the try macro on certain calls however I don’t seem to be able to use this in conjunction with returning the std::error::Error trait in the result. Here is a sample of my code, I’m aware that if this error were fixed that the code still wouldn’t compile, I’m just trying to solve this error handling approach.

extern crate rustc_serialize;
extern crate toml;

use std::fs::File;
use std::io::Read;
use std::error::Error;

#[derive(RustcDecodable)]
struct Manifest {
    name: String,
    url: String,
}

fn main() {
    let val = parseManifest("./manifest.toml");
    // println!("{:}?", val.unwrap());
}

fn parseManifest(path: &str) -> Result<Manifest, &Error> {
    let mut file = try!(File::open(path));
    let mut tomlString = String::new();
    try!(file.read_to_string(&mut tomlString));

    match toml::decode_str::<Manifest>(tomlString) {
        Some(manifest)  => Ok(manifest),
        None            => Err("failed to parse manifest")
    }
}

Result of cargo run:

<std macros>:6:1: 6:32 error: the trait `core::convert::From<std::io::error::Error>` is not implemented for the type `&std::error::Error` [E0277]
<std macros>:6 $ crate:: convert:: From:: from ( err ) ) } } )
               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<std macros>:1:1: 6:48 note: in expansion of try!
src/main.rs:21:20: 21:42 note: expansion site
<std macros>:6:1: 6:32 error: the trait `core::convert::From<std::io::error::Error>` is not implemented for the type `&std::error::Error` [E0277]
<std macros>:6 $ crate:: convert:: From:: from ( err ) ) } } )
               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<std macros>:1:1: 6:48 note: in expansion of try!
src/main.rs:23:5: 23:48 note: expansion site

#2

You probably want Box<Error> instead of &Error.


#3

Additionally, you’ll need to convert that &str into an error. There are other ways to do this but the following works: Err(Box::<Error + Sync + Send>::from(String::from("failed to parse manifest")). Type inference fails here because the traits don’t quite match.


#4

@stebalien @gkoz Cheers Guys, it’s sorted.