If you will notice from the previous example, when we call parse, the immediate reaction
is to map the error from a library error into our new custom error type.
.and_then(|s| s.parse::<i32>()
    .map_err(DoubleError::Parse)
This is a very simple and also common operation so it would be convenient if eliding it
would work but alas, it does not. and_then is not sufficiently flexible that it can handle
this; try! is though.
try! has previously been explained as either unwrap or return Err(err) which is only
93% correct. It actually means unwrap or return Err(From::from(err)). Since From::from
is a conversion utility between different types, this means if you try! something where the
error is convertible to the return type, it will convert automatically. This means, if we
rewrite this example with try! when From::from is implemented for our error type,
the map_err will go away:
This is actually fairly clean now. If you compare it with the original panic, it is very similar
to replacing the unwrap calls with try! except that the return types are Result and so
they must be destructured at the top level.
However, do not expect error handling of this sort to replace all usage of unwrap in
practice. Error handling of this sort tripled our code line count and cannot really be
called simple even if this is heavily biased by the small code size. Indeed, moving a 1000 line
library from unwrap to more proper error handling might be feasible in an additional
100 lines of code though the necessary refractoring definitely would not be trivial.
This is a very reasonable place to be. Many libraries might get away with only
implementing Display and then adding From on an as needed basis. A serious library
though will have users with certain expections about how it should implement error handling.
In those cases, the error handling will need to be taken one step further.
From::from and try!