`Parity` conversion and error handling cleanup

This removes the deprecated `From` conversion and adds a new error
type for the invalid parity error with a conversion to the catch-all
`Error`.
This commit is contained in:
Martin Habovstiak 2022-02-10 23:50:02 +01:00
parent c7d6cdbaba
commit 5acf6d23d3
2 changed files with 54 additions and 21 deletions

View File

@ -1134,7 +1134,7 @@ impl XOnlyPublicKey {
return Err(Error::InvalidPublicKey); return Err(Error::InvalidPublicKey);
} }
Parity::from_i32(parity) Parity::from_i32(parity).map_err(Into::into)
} }
} }
@ -1219,7 +1219,7 @@ impl Parity {
/// ///
/// The only allowed values are `0` meaning even parity and `1` meaning odd. /// The only allowed values are `0` meaning even parity and `1` meaning odd.
/// Other values result in error being returned. /// Other values result in error being returned.
pub fn from_u8(parity: u8) -> Result<Parity, Error> { pub fn from_u8(parity: u8) -> Result<Parity, InvalidParityValue> {
Parity::from_i32(parity.into()) Parity::from_i32(parity.into())
} }
@ -1227,25 +1227,11 @@ impl Parity {
/// ///
/// The only allowed values are `0` meaning even parity and `1` meaning odd. /// The only allowed values are `0` meaning even parity and `1` meaning odd.
/// Other values result in error being returned. /// Other values result in error being returned.
pub fn from_i32(parity: i32) -> Result<Parity, Error> { pub fn from_i32(parity: i32) -> Result<Parity, InvalidParityValue> {
match parity { match parity {
0 => Ok(Parity::Even), 0 => Ok(Parity::Even),
1 => Ok(Parity::Odd), 1 => Ok(Parity::Odd),
_ => Err(Error::InvalidParityValue), _ => Err(InvalidParityValue(parity)),
}
}
}
impl From<i32> for Parity {
/// Please note, this method is deprecated and will be removed in an upcoming release, it
/// is **not** equivalent to `from_u32()`, it is better to use `Parity::from_u32`.
///
/// This method returns same parity as the parity of input integer.
fn from(parity: i32) -> Parity {
if parity % 2 == 0 {
Parity::Even
} else {
Parity::Odd
} }
} }
} }
@ -1257,6 +1243,13 @@ impl From<Parity> for i32 {
} }
} }
/// The conversion returns `0` for even parity and `1` for odd.
impl From<Parity> for u8 {
fn from(parity: Parity) -> u8 {
parity.to_u8()
}
}
/// Returns even parity if the operands are equal, odd otherwise. /// Returns even parity if the operands are equal, odd otherwise.
impl BitXor for Parity { impl BitXor for Parity {
type Output = Parity; type Output = Parity;
@ -1271,6 +1264,30 @@ impl BitXor for Parity {
} }
} }
/// Error returned when conversion from an integer to `Parity` fails.
//
// Note that we don't allow inspecting the value because we may change the type.
// Yes, this comment is intentionally NOT doc comment.
// Too many derives for compatibility with current Error type.
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)]
pub struct InvalidParityValue(i32);
impl fmt::Display for InvalidParityValue {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "invalid value {} for Parity - must be 0 or 1", self.0)
}
}
#[cfg(feature = "std")]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
impl ::std::error::Error for InvalidParityValue {}
impl From<InvalidParityValue> for Error {
fn from(error: InvalidParityValue) -> Self {
Error::InvalidParityValue(error)
}
}
/// The parity is serialized as `u8` - `0` for even, `1` for odd. /// The parity is serialized as `u8` - `0` for even, `1` for odd.
#[cfg(feature = "serde")] #[cfg(feature = "serde")]
#[cfg_attr(docsrs, doc(cfg(feature = "serde")))] #[cfg_attr(docsrs, doc(cfg(feature = "serde")))]

View File

@ -361,7 +361,7 @@ pub enum Error {
/// Bad set of public keys. /// Bad set of public keys.
InvalidPublicKeySum, InvalidPublicKeySum,
/// The only valid parity values are 0 or 1. /// The only valid parity values are 0 or 1.
InvalidParityValue, InvalidParityValue(key::InvalidParityValue),
} }
impl Error { impl Error {
@ -376,7 +376,7 @@ impl Error {
Error::InvalidTweak => "secp: bad tweak", Error::InvalidTweak => "secp: bad tweak",
Error::NotEnoughMemory => "secp: not enough memory allocated", Error::NotEnoughMemory => "secp: not enough memory allocated",
Error::InvalidPublicKeySum => "secp: the sum of public keys was invalid or the input vector lengths was less than 1", Error::InvalidPublicKeySum => "secp: the sum of public keys was invalid or the input vector lengths was less than 1",
Error::InvalidParityValue => "The only valid parity values are 0 or 1", Error::InvalidParityValue(_) => "couldn't create parity",
} }
} }
} }
@ -390,7 +390,23 @@ impl fmt::Display for Error {
#[cfg(feature = "std")] #[cfg(feature = "std")]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))] #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
impl std::error::Error for Error {} impl std::error::Error for Error {
#[allow(deprecated)]
fn cause(&self) -> Option<&dyn std::error::Error> {
match self {
Error::IncorrectSignature => None,
Error::InvalidMessage => None,
Error::InvalidPublicKey => None,
Error::InvalidSignature => None,
Error::InvalidSecretKey => None,
Error::InvalidRecoveryId => None,
Error::InvalidTweak => None,
Error::NotEnoughMemory => None,
Error::InvalidPublicKeySum => None,
Error::InvalidParityValue(error) => Some(error),
}
}
}
/// The secp256k1 engine, used to execute all signature operations. /// The secp256k1 engine, used to execute all signature operations.