strum
strum copied to clipboard
EnumString macro ignores parse_err_ty when there is a default variant
Related to https://github.com/Peternator7/strum/issues/307
In theory, this new feature of EnumString should allow infallible parsing of an enum with a default variant:
The default error type is
strum::ParseError. This can be overridden by applying both theparse_err_tyandparse_err_fnattributes at the type level.parse_error_fnshould be a function that accepts an&strand returns the typeparse_error_ty.
(aside: there are some stray references to parse_error_fn and parse_error_ty)
Unfortunately, https://github.com/Peternator7/strum/pull/380/ that added the feature explicitly sets the error type back to strum::ParseError if the enum has a default variant, see here.
Thus, the following:
#[derive(EnumString)]
#[strum(
parse_err_fn = not_needed_because_parsing_is_infallible,
parse_err_ty = std::convert::Infallible,
)]
pub enum InfallibleEnum {
Foo,
Bar,
#[strum(default)]
Unknown(String),
}
fn parse_infallible(s: &str) -> Result<InfallibleEnum, std::convert::Infallible> {
s.parse()
}
fails to compile with:
error[E0271]: type mismatch resolving `<InfallibleEnum as FromStr>::Err == Infallible`
--> test.rs:24:7
|
24 | s.parse()
| ^^^^^ expected `ParseError`, found `Infallible`
For more information about this error, try `rustc --explain E0271`.
Perhaps this was just an oversight in the original PR? Or is there a specific (but undocumented) reason it's important for enums with default variants to ignore the custom error type specification?
The expanded macro code confirms the custom error type was ignored:
#[allow(clippy::use_self)]
impl ::core::str::FromStr for InfallibleEnum {
type Err = ::strum::ParseError;
#[inline]
fn from_str(
s: &str,
) -> ::core::result::Result<
InfallibleEnum,
<Self as ::core::str::FromStr>::Err,
> {
::core::result::Result::Ok(
match s {
"Foo" => InfallibleEnum::Foo,
"Bar" => InfallibleEnum::Bar,
_ => {
return ::core::result::Result::Ok(
InfallibleEnum::Unknown(s.into()),
);
}
},
)
}
}