The thing is one needs to capture the second variant of the data, due there is many functions that returns a Result or an Option, or even some libraries a Result<Option>. I mean sugars for match for dealing with monads.
Basically would be great being able to destructure as quickly and clean as possible the monads. I mean, to manage the possible errors or limits what returns a function, for proceeding to work with the data.
// this code is inside of a function, so have to use return if needed.
let Ok(data) = res else Err(e) { log(e); return Err("Custom err"); };
// And one starts working with data
let Ok(data) = res else Err(e) { log(e); default };
// And one starts working with data
.
One usually also wants to try a second way for assigning the data:
let Ok(data) = res else Err(e) {
res2 else Err(e2) {
log(e, e2);
return Err("res and res2 failed");
}
};
.
And sometimes things like this, trying to escape from match towers as much as possible:
let Ok(data2) = res else Err(e) {
match e {
Errortypet1() =>
{
res2 else Err(e2){
log(e, e2);
return Err("failed res, tryed res2 and also failed");
}
},
Errortypet4() =>
{
opt2 else None {
log(e, "none");
return Err("res and opt failed");
}
},
_ =>{ log("unknown error"); return Err("unknown error"); }
}
};
// And one starts working with data
fn handle_input(input: Input) -> Result<(), CustomError> {
let data = parse_data(input)?;
// with default:
let data = parse_data(input)
.map_err(|e| { log(e); default })
.into_ok_or_err();
}
fn parse_data(input: Input) -> Result<Data, ParseError> { /*...*/ }
impl From<ParseError> for CustomError {
fn from(e: ParseError) -> CustomError {
log(e);
CustomError::new("Custom err")
}
}
Here I would use this:
let data = match res {
Ok(data) => data,
Err(e) => match res2 {
Ok(data) => data,
Err(e2) => {
log(e);
log(e2);
return Err("res and res2 failed");
}
}
};
You can pattern match deeper into your types like this:
let Ok(data) = match res {
Ok(data) => data,
Err(e@Errortypet1()) => match res2 {
Ok(data) => data,
Err(e2) => {
log(e);
log(e2);
return Err("failed res, tryed res2 and also failed");
}
}
Err(e@Errortypet4()) => match opt2 {
// here one could use let-else
Some(data) => data,
None => {
log(e, "none");
return Err("res and opt failed");
}
},
Err(_) => {
log("unknown error");
return Err("unknown error");
}
};