Returning error from trait impl


#1

I have a function that converts two types to a third type and errors out if it cannot.
fn from_addr_and_mask(addr: T,mask: T) -> Result<TT, TErr>. I’m trying to convert this to an implementation of From<(T,T)>. Is there a way to return a Result from this trait impl?


#2

Note: this trait must not fail. If the conversion can fail, use TryFrom or a dedicated method which returns an Option or a Result<T, E>.

Source: the docu.

So no, From is defined as returning Self, you can’t change that.


#3

Thanks @jer!


#4

It’s possible to cheat this by implementing this on Result itself, as long as you’re careful to dodge orphan errors. Something like this:

struct Foo(u32); // newtype to avoid orphan errors
type FooResult = Result<u32, &'static str>; // just for convenience

impl From<Foo> for FooResult {
    fn from(x: Foo) -> Self {
        let x = x.0;
        if x < 42 { Ok(x) } else { Err("too big!") }
    }
}

fn main() {
    for x in &[1, 10, 100] {
        let r: FooResult = Foo(*x).into();
        println!("{} -> {:?}", x, r);
    }
}

playground

1 -> Ok(1)
10 -> Ok(10)
100 -> Err("too big!")

#5

Doing something like this is not recommended, though; you should use TryFrom (which is admittedly not stabilized yet).


#6

I did say it was cheating. :smile:

That might be a little instructive though, in that it is possible within the orphan rules to implement a foreign trait for a foreign type, as long as you have a local type in the right place. Perhaps a more productive use could be something like impl From<Foo> for Vec<Bar>.