The tl;dr: I want to add a convenience method to convert Result<(), ump::Error<MyError>>
to ControlFlow<MyError, ()>
.
Given the trait:
trait ToControlFlow {
fn to_ctrlflow(self) -> ControlFlow<MyError, ()>;
}
Why does this not work:
impl ToControlFlow for Result<(), ump::Error<MyError>> {
.. while this does?
impl<E> ToControlFlow for Result<(), E> {
(Given that E
indeed is ump::Error<MyError>
)
I get the error:
error[E0599]: no method named `to_ctrlflow` found for enum `Result` in the current scope
--> src/main.rs:37:18
|
37 | rctx.reply(42).to_ctrlflow()
| ^^^^^^^^^^^ method not found in `Result<(), Error<MyError>>`
|
= help: items from traits can only be used if the trait is implemented and in scope
note: `ToControlFlow` defines an item `to_ctrlflow`, perhaps you need to implement it
Minimal test case main.rs
, used with ump = "0.10.2"
:
use std::ops::ControlFlow;
#[derive(Debug, PartialEq)]
pub enum MyError {
Internal
}
/// Convenience trait used to map `Result<(), ump::Error<MyError>>` to
/// `ControlFlow<MyError, ()>`.
trait ToControlFlow {
fn to_ctrlflow(self) -> ControlFlow<MyError, ()>;
}
// Why doesn't this work?
//impl ToControlFlow for Result<(), ump::Error<MyError>> {
impl<E> ToControlFlow for Result<(), E> {
fn to_ctrlflow(self) -> ControlFlow<MyError, ()> {
self.map_or_else(
|_| ControlFlow::Break(MyError::Internal),
|_| ControlFlow::Continue(())
)
}
}
fn main() {
let (server, _client) = ump::channel::<u32, u32, MyError>();
let _ = service(server);
}
fn service(
server: ump::Server<u32, u32, MyError>
) -> ControlFlow<MyError, ()> {
let (_msg, rctx) = server.wait().unwrap();
// .reply() returns `Result<(), ump::Error<E>>`, and E is `MyError` here.
rctx.reply(42).to_ctrlflow()
}