-
Notifications
You must be signed in to change notification settings - Fork 5
Feature To Handle Disjointedness #14
Description
Originally covered by the defunct coerce_macro. A new feature flag should be added for a way to handle disjointedness. E.g.
Given
error_set! {
Error1 = {
Variant1,
Variant2,
};
Error2 = {
Variant2,
}
}Option 1
Generates methods to handled disjointedness
fn main() {
let error: Error2 = Error1::Variant1.into_error2().variant1(|| Error2::Varient2);
let result: Result<(), Error2> = Err(Error1::Variant1).into_error2().variant1(|| Err(Error2::Varient2));
}The builder pattern is used to guard against the case where rearranging the original error definition might cause unintended behavior (passing to the wrong arg). Its probably best to keep the methods in order of variant fields. This would limit the number of structs with fields generated. No need to call build() at the end, since we'll know the last one is the last field that needs specifying.
Drawbacks:
Consider this case
fn main() -> Result<(), Error2> {
let result: Result<i32, Error1> = Ok(-1);
let either: Either<usize,i32> = result.map(|e| Either::Right(e)).into_error2().variant1(|| Ok(Either::Left(1)))?;
match either {
Either::Left(left) => ...,
Either::Right(right) => ...,
}
...
}Some scenarios may require using a sum type like Either, if you want to do something with a value that is neither the target Err type or the current Ok type.
Option 2
Bring back the coerce_macro.
All that would be need is to implemented handling any new features.
Drawbacks:
- Not the best syntax, plus formatting does not work in macros.
- requires using another macro
Option 3
Don't add anything. Handling disjointedness should be done directly by the user
fn main() -> Result<(), Error2> {
let result: Result<i32, Error1> = Ok(-1);
let result: Result<i32, Error2> = match result {
Ok(ok) => Ok(ok),
Err(err) => match err {
Error1::Variant1 => ..., // handle
Error1:: Variant2 => Err(Error2::Variant2),
}
}Drawbacks:
- Verbose
- Mappings could easily become wrong with mistakes or refactors (e.g.
Error1::Variant1 => Err(Error2::Variant2))