Here is an example of it in action:
let msg = stream.next().await.context("expected a message")??;
Is it just ? being done twice? If so why does it need to be done in this case?
Yes, it's just ? being done twice; there is no ?? operator.
stream is a WsStream. WsStream is a type defined in the same module. WsStream implements Stream.
stream.next() invokes StreamExt::next, which returns a future that yields Option<Self::Item>. Self::Item is defined to be tungstenite::Result<Message> (= Result<Message, tungstenite::Error>) for WsStream. This means that the result of stream.next().await is of type Option<Result<Message, tungstenite::Error>>.
Then, context is applied on the value. Context is implemented for Option<T> and for Result<T, E>, but the output is always a Result. However, context doesn't flatten anything, so we end up with Result<Result<Message, tungstenite::Error>, anyhow::Error>. The two uses of ? therefore serve to handle the two levels of Results.
Yes, it's just the ? operator done twice. A quick example:
fn result_of_result() -> Result<Result<i32, String>, String> {
Ok(Ok(42))
}
fn f() -> Result<(), String> {
println!("{:?}", result_of_result());
println!("{:?}", result_of_result()?);
println!("{:?}", result_of_result()??);
Ok(())
}
fn main() {f();}
Outputs:
Ok(Ok(42))
Ok(42)
42
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With