Clean conditional return statements

I get where your comming from, but what about a return value if condition like so:


fn validate_admin(user:&User)->Result<(),UserValidationError>{
    return Err(UserValidationError::UsernameToShort) if user.name.len() < 3;
    return Err(UserValidationError::UsernameToLong) if user.name.len() > 20;
    return Err(UserValidationError::NotAnAdmin) if !user.is_admin;
    Ok(())
}

Since you should always start with the weakest construct -- language changes are a last resort -- how about a function?

fn require<E>(cond: bool, err: E) -> Result<(), E> {
    if cond { Err(err) } else { Ok(()) }}
}

pub fn validate_admin(user:&User)->Result<(),UserValidationError>{
    require(user.name.len() >= 3, UserValidationError::UsernameToShort)?;
    require(user.name.len() <= 20, UserValidationError::UsernameToLong)?;
    require(user.is_admin, UserValidationError::NotAnAdmin)?;
    Ok(())
}

(Or make a macro if you want to shorten it further.)

6 Likes

Guys, I have a bad idea. This gets formatted as a single line:

let false = condition() else { return }; 
11 Likes

Another stupid/fun alternative:

(user.name.len() < 3).then_some(()).ok_or(UserValidationError::UsernameToShort)?;
2 Likes

The third one is easily most readable to me. "If this isn't true, then don't do the next thing" isn't really great IMO. But that is just your example which has double negation.

In general, I prefer if there is only one way to do something. For example, generic bounds can be either in the <> brackets, or in the where clause. This just leads to decision fatigue and inconsistencies, where one function have it one way, and another function another way. Not saying that is necessarily bad, but it's slightly annoying for me.

And your proposed syntax would kind of do the same thing - add multiple ways or returning from a function. Yes, Rust has the ? operator, but that is for Try specifically. I just don't see the added value, especially if you can do the same thing with a macro.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.