I prefer to use explicit return statements everywhere -- for greppability.
I'd even say any return is actually one too many.
If !validation_rule1 { return default/err }
If !validation_rule2 { return default/err }
Work…
If !validation_rule3 { return default/err }
Work…
return result/success
Don’t know how you’d get away with single return except by horrifically nesting conditionalsThat pattern is addressed by chained not nested conditionals, which can then be wrapped in a match, i.e.:
if !validation1 { err1 }
else if !validation1 { err2 }
.
.
.
else {
...work...;
success_result
}
the error checking part can be reduced to an iteration with appropriate definitions of a structure for the data to be validated, etc., like: match validators.find_map(|v| v(data)) {
Some(err) => err,
None => { ...work...; success_result }
}
EDIT:I missed the intermediate work steps in your post when I initially wrote the response. That can be done a number of ways, e.g., breaking things up into to chained steps (each of which might use the above pattern) that mix validation and work and return a Result type with either the data for the next step to consume or an error.
(validation_rule1')
.and_then(validation_rule2')
.and_then(work1)
.and_then(validation_rule3')
.and_then(work)