Bob, Dig Deeper: Possible Improvement?

Not a duplicate ;-)

I’ve just looked at the “dig deeper” section for “bob” and I wondered if the current approach for " match on a tuple" could possibly be improved - or if the following is less idiomatic?

pub fn reply(message: &str) -> &str {
    let trimmed = message.trim();
    match (
        /* mute    */ trimmed.is_empty(),
        /* yelling */ trimmed == trimmed.to_uppercase() && trimmed != trimmed.to_lowercase(),
        /* asking  */ trimmed.ends_with("?"),
    ) {
        (true, _, _) => "Fine. Be that way!",
        (_, true, true) => "Calm down, I know what I'm doing!",
        (_, true, _) => "Whoa, chill out!",
        (_, _, true) => "Sure.",
        _ => "Whatever.",
    }
}

It just seems weird to me that we handle one case in a condition and the rest with match-ing. Of course it would be even better if we could use a name instead of a comment in the match. I realize we could also allocate local variables (and even save one line), but somehow that seems slightly harder to read - or is that just me not used to the language yet?

pub fn reply(message: &str) -> &str {
    let trimmed = message.trim();
    let mute = trimmed.is_empty();
    let yelling = trimmed == trimmed.to_uppercase() && trimmed != trimmed.to_lowercase();
    let asking = trimmed.ends_with("?");
    match (mute, yelling, asking) {
        (true, _, _) => "Fine. Be that way!",
        (_, true, true) => "Calm down, I know what I'm doing!",
        (_, true, _) => "Whoa, chill out!",
        (_, _, true) => "Sure.",
        _ => "Whatever.",
    }
}

Same question for the “if statements” approach, do rustaceans dislike keeping conditional return statements on one line? And generally, wouldn’t we rather use && than nested conditions? Here’s my take on it:

pub fn reply(message: &str) -> &str {
    let trimmed = message.trim();
    if trimmed.is_empty() { return "Fine. Be that way!"; }

    let is_question = trimmed.ends_with("?");
    let is_yelling = trimmed == trimmed.to_uppercase() && trimmed != trimmed.to_lowercase();

    if is_question && is_yelling { return "Calm down, I know what I'm doing!"; }
    if is_question { return "Sure."; }
    if is_yelling { return "Whoa, chill out!"; }
  
    "Whatever."
}

Let me know if this is not helpful, I’ll just keep my thoughts to myself ;-) And of course, if you think it does help, I’ll be happy to provide a PR.

It doesn’t seem that weird to me. The first check if the message is empty is completely separate logically from the other conditions. “yelling” and “asking” are logically connected so the match is useful here.

rustfmt doesn’t like it, which means rustaceans don’t have to think about it :wink:

I don’t think there’s a right or wrong answer to that question, it’s a preference. I personally don’t think it’s important. It does the same thing.


In this particular case, I don’t see a reason to change the existing approaches, but it’s always good to discuss :slightly_smiling_face: so please keep sharing your thoughts as you explore the Rust track.

1 Like