I’m trying to parse some user input, the input is stored in a struct where there are a lot of options/results (to deal with the data being uninitialized before the user enters it) and when the user submits it it needs to go into a struct where all the values are known.
I’d like to be able to a vector with any errors so I can give feedback to the user on all the errors with the input (not just the first). However, I can’t find a good way to do that.
struct Test {
x: i32,
y: String,
}
#[derive(Debug)]
enum Errors {
OneIsNone,
TwoIsNone,
}
The my current approach is:
fn main() -> Result<Test, Vec<Errors>> {
let option1 = Some(5);
let option2 = None;
let mut errors = Vec::new();
let x: i32;
match option1 {
Some(value) => x = value,
None => errors.push(Errors::OneIsNone),
};
let y: String;
match option2 {
Some(value) => y = value,
None => errors.push(Errors::TwoIsNone),
}
if errors.len() != 0 {
return Err(errors)
}
Ok(
Test {
x,
y
}
)
}
Which doesn’t work because the compiler can’t tell that x and y must be initialised if the code reaches the Ok
block.
In this case I could just unwrap match the two results but that approach will become hideously clunky for structs with a large number of fields.
Basically I want a way to take in a large number of results and parse them into a struct if they all give Ok()
or return a vector containing all the errors otherwise i.e. how to I implement unwrap_or_errors
in
fn main() -> Result<Test, Vec<Errors>> {
let option1 = Some(5);
let option2 = None;
let mut errors = Vec::new();
let x = match option1 {
Some(val) => Ok(val),
None => Err(Errors::OneIsNone),
};
let y = match option2 {
Some(val) => Ok(val),
None => Err(Errors::TwoIsNone),
};
if errors.len() != 0 {
return Err(errors)
}
Test::unwrap_or_errors(x, y)?
}