> Don’t know how you’d get away with single return except by horrifically nesting conditionals
That 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.