So I have an EmailAddress
and want to have a custom response when serde fails to deserialize it.
impl EmailAddress {
pub fn parse(s: String) -> Result<Self, EmailAddressParseError> {
match validate_email(&s) {
true => Ok(Self(s)),
false => Err(EmailAddressParseError),
}
}
}
#[derive(Debug)]
pub struct EmailAddressParseError;
impl std::fmt::Display for EmailAddressParseError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "Email validation failed")
}
}
impl std::error::Error for EmailAddressParseError {}
impl de::Error for EmailAddressParseError {
fn custom<T>(_msg: T) -> Self
where
T: fmt::Display,
{
Self // I always and only want the text "Email validation failed"
}
}
struct EmailAddressVisitor;
impl<'de> Visitor<'de> for EmailAddressVisitor {
type Value = EmailAddress;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a valid email address")
}
fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
where
E: de::Error,
{
// Attempt 1:
// Simply return: `EmailAddress::parse(value.to_string())`
// Even though this method returns a Result<_, EmailAddressParseError>
// which impls de::Error, rust won't let me return it with the error:
// ```
// mismatched types
// expected enum `Result<_, E>`
// found enum `Result<_, EmailAddressParseError>`
// ```
// Attempt 2:
EmailAddress::parse(value.to_string()).map_err(|e| E::custom(e))
}
}
As it currently stands, I do get my custom "Email validation failed" error message, but it's prefixed with "Parse error: "
is there anyway to remove that?