I know a number of people have been wanting this, but I hadn’t seen any implementations of it. In a few minutes, I threw together an implementation that I believe is backward compatible.
Comments or criticisms are welcome.
I know a number of people have been wanting this, but I hadn’t seen any implementations of it. In a few minutes, I threw together an implementation that I believe is backward compatible.
Comments or criticisms are welcome.
so this allows using the try!
macro on any implementor of the Try
trait?
Yes, precisely.
Is .ok_or()
not terse enough?
The reason that ok_or
is not enough is that the value that try!()
adds is the return on non-happy path behavior. Sometimes you just really want to bubble up the sad case without worrying about it in your method chaining.
Using .ok_or
with try!
returns a Result
from the function. The idea with this implementation is that try!(some_option)
would return None
from the function when some_option
is None
.
I think that Try::try
should use its own struct for the return type.
enum FlowPath<H, B> {
Happy(H),
Bubble(B)
}
With whatever bikeshedding you want for the names. (Probably do research into what Programming Language Theory calls these things?)
And then, you’d have Try::try(self) -> FlowPath<H, B>
.
Basically, don’t overload Result
into Either
and instead create your own structurally equivalent type. It’d make the code semantically more readable.
Actually, I’m going to fork and show what it’d look like.
Edit: Done here: https://github.com/Havvy/try/tree/patch-1
Oh okay, cool. Neat. I thought it just elevated the Option
to a Result
. Sorry.
Looks really useful, any plans to make this an RFC?
Yeah, I’ll start writing up an RFC now.
I’m not sure if this really has a strong motivation. “It would be neat.” is not very compelling. I only found about 30 cases of None => return None
in all the Rust compiler/stdlib code.
Does anyone have any ideas for other types that might benefit from implementing Try
?
FWIW I have a similar trait (called Carrier) in the trait-based exception handling RFC.
Here is another attempt at this https://github.com/SimonSapin/rust-std-candidates/blob/master/triable/lib.rs
Well, dang. I tried compiling my implementation in std
and it fails with a type inference error:
src/libstd/try.rs:77:21: 77:36 error: type annotations required: cannot resolve `_ : try::Try<collections::vec::Vec<net::addr::SocketAddr>, core::result::Result<collections::vec::IntoIter<net::addr::SocketAddr>, io::error::Error>>` [E0283]
src/libstd/try.rs:77 match $crate::try::Try::try($e) {
^~~~~~~~~~~~~~~
src/libstd/try.rs:75:1: 82:2 note: in expansion of try!
src/libstd/net/addr.rs:385:21: 397:18 note: expansion site
src/libstd/try.rs:77:21: 77:36 note: required by `try::Try::try`
src/libstd/try.rs:77 match $crate::try::Try::try($e) {
^~~~~~~~~~~~~~~
src/libstd/try.rs:75:1: 82:2 note: in expansion of try!
src/libstd/net/addr.rs:385:21: 397:18 note: expansion site
error: aborting due to previous error
So, it’s not backward compatible. Game over.
I have a pretty good use case for this. I’m writing a chat server which should ideally never crash, so I’m doing the usual check all options and results and “handle” them. But in a lot of cases the unwraps are really just protecting me from things which I cannot reasonably recover from, so rather than crash I’d like to have some unified logic for logging these events. The recovery logic should be applicable to both Option<T>
and Result<T, E>
.
More fundametally it’s obvious Option
and Result
need unification as their functions overlap a lot.
This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.