Return type for component validation with both errors and warnings?

I have a hierarchy of components which I need to validate. The validation should result in either ok/no warnings, a warning, or an error. Errors take the highest precedence and should be returned immediately. Warnings on the other hand should allow the validation to continue in case there are errors during the later stages of validation (which take priority). The following code snippet is my current solution where the Option represents an optional warning:

pub fn validate(&self) -> Result<Option<String>, String> {
    Ok(self.child_component1.validate()?
        .or(self.child_component2.validate()?))
}

Are there any better patterns for solving this problem?

An alternative could be

fn validate(&self, w: &mut Option<String>) -> Result<(), String> {
    self.child_component1.validate(w)?;
    self.child_component2.validate(w)?;
    Ok(())
}

The idea is that any warning encountered would be written to the w (short for “warning”) container, unless there already is a warning (e.g. by using the get_or_insert function and ignoring its return value); and on error the error String is returned through the Result.

To wrap this all up nicely, you could write a function to be called at the top level that can return a nice enum. E.g.

fn validation(&self) -> ValidationResult {
    let mut w = None;
    match (self.validate(&mut w), w) {
        (Ok(()), None) => ValidationResult::Ok,
        (Ok(()), Some(warning)) => ValidationResult::Warning(warning),
        (Err(error), _) => ValidationResult::Error(error),
    }
}

You could also consider changing the w from &mut Option<String> to a &mut Vec<String> in case you want to collect and return all warnings.

2 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.