Analog of ? but for when the return type if not Result

impl AsyncRead for SmolSocket {
    fn poll_read(
        mut self: Pin<&mut Self>,
        cx: &mut Context<'_>,
        buf: &mut tokio::io::ReadBuf<'_>,
    ) -> Poll<std::io::Result<()>> {
        //closure because Poll does not implement clone
        let packet_missing = ||{Poll::Ready(Err(std::io::Error::new(std::io::ErrorKind::InvalidData, "tcp packet missing")))};
        let tcp_packet = match &packet.tcp {
            Some(packet) => packet,
            None => return packet_missing()
        };

Since the return type of poll_read is not a Result, I cannot do

let tcp_packet = &packet.tcp.unwrap_or(packet_missing)?

to return the value. I have to do this match everytime, and I need to do it more than once, so it's ugly to leave it like this. I think the ready! macro would solve this but it is experimental std::task::ready - Rust

Is there a more elegant solution?

1 Like

Poll<Result<T, E>> and Poll<Option<T>> implement the Try trait, so they can be used with the ? operator:

let tcp_packet = packet.tcp.as_ref().ok_or(
    io::Error::new(ErrorKind::InvalidData, "tcp packet missing"))?;

There's also been some renewed activity on my old RFC 1303 (let...else) which could help for other use cases like this.

3 Likes