How do I ensure multiple statements all return Some?

Viewed 81
let message = tokens.pop().expect("rabl_server encountered login error #send_message()");
let target = tokens.pop().expect("rabl_server encountered login error #send_message()");
let sender = tokens.pop().expect("rabl_server encountered login error #send_message()");

Currently have this code right now that tries to pull a few elements from a vector (that I have already ensured has the proper number of elements) and am wondering if there is some standard way to achieve a similar result as the one above, and check that ALL operations returned Some at once, instead of essentially writing the same .expect() statement three times? Thanks.

1 Answers

You say you have ensured that the vector has the right number of elements, which I take to mean you guarantee that the pop()s all return Some(_). An alternative could be:

fn main() {
    let mut tokens = vec!["1", "2", "3"];

    let mut i = tokens.drain(..3);
    match (i.next(), i.next(), i.next()) {
        (Some(message), Some(target), Some(sender)) => {
            println!("do something: {} {} {} ", message, target, sender);
        }
        _ => unreachable!(),
    }
}

drain() will panic if the range is not correct so this is ok to call unreachable.

Since you say you don't want to repeat expect I also assume you don't want to just repeat unwrap(). The above code minimizes repetition while also communicating that only Some will be returned.

If you don't need ownership you can use as_slice() and use slice pattern matching:

match tokens.drain(..3).as_slice() {
    [message, target, sender] => {
        println!("do something: {} {} {} ", message, target, sender);
    }
    _ => unreachable!(),
};
Related