Skip to content

Commit dc90a43

Browse files
committed
Merge #403: Parity conversion and error handling cleanup
5acf6d2 `Parity` conversion and error handling cleanup (Martin Habovstiak) Pull request description: This removes the deprecated `From` conversion, replaces it with `TryFrom`, and adds more convenience conversions. A new error type is created for the invalid parity error with conversion to catch-all `Error`. This is intended for an API-breaking version. ACKs for top commit: apoelstra: ACK 5acf6d2 Tree-SHA512: 49b73fc90455c172012b46f36eafa7d256b940f4b431b4eedb577ab07d9402eae40af931e00b3c409bbe502dbcac064a742e874a5e8bedd8d0cbe92a468ae4f6
2 parents ab6df6f + 5acf6d2 commit dc90a43

File tree

2 files changed

+54
-21
lines changed

2 files changed

+54
-21
lines changed

src/key.rs

Lines changed: 35 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1134,7 +1134,7 @@ impl XOnlyPublicKey {
11341134
return Err(Error::InvalidPublicKey);
11351135
}
11361136

1137-
Parity::from_i32(parity)
1137+
Parity::from_i32(parity).map_err(Into::into)
11381138
}
11391139
}
11401140

@@ -1219,33 +1219,19 @@ impl Parity {
12191219
///
12201220
/// The only allowed values are `0` meaning even parity and `1` meaning odd.
12211221
/// Other values result in error being returned.
1222-
pub fn from_u8(parity: u8) -> Result<Parity, Error> {
1222+
pub fn from_u8(parity: u8) -> Result<Parity, InvalidParityValue> {
12231223
Parity::from_i32(parity.into())
12241224
}
12251225

12261226
/// Constructs a [`Parity`] from a signed integer.
12271227
///
12281228
/// The only allowed values are `0` meaning even parity and `1` meaning odd.
12291229
/// Other values result in error being returned.
1230-
pub fn from_i32(parity: i32) -> Result<Parity, Error> {
1230+
pub fn from_i32(parity: i32) -> Result<Parity, InvalidParityValue> {
12311231
match parity {
12321232
0 => Ok(Parity::Even),
12331233
1 => Ok(Parity::Odd),
1234-
_ => Err(Error::InvalidParityValue),
1235-
}
1236-
}
1237-
}
1238-
1239-
impl From<i32> for Parity {
1240-
/// Please note, this method is deprecated and will be removed in an upcoming release, it
1241-
/// is **not** equivalent to `from_u32()`, it is better to use `Parity::from_u32`.
1242-
///
1243-
/// This method returns same parity as the parity of input integer.
1244-
fn from(parity: i32) -> Parity {
1245-
if parity % 2 == 0 {
1246-
Parity::Even
1247-
} else {
1248-
Parity::Odd
1234+
_ => Err(InvalidParityValue(parity)),
12491235
}
12501236
}
12511237
}
@@ -1257,6 +1243,13 @@ impl From<Parity> for i32 {
12571243
}
12581244
}
12591245

1246+
/// The conversion returns `0` for even parity and `1` for odd.
1247+
impl From<Parity> for u8 {
1248+
fn from(parity: Parity) -> u8 {
1249+
parity.to_u8()
1250+
}
1251+
}
1252+
12601253
/// Returns even parity if the operands are equal, odd otherwise.
12611254
impl BitXor for Parity {
12621255
type Output = Parity;
@@ -1271,6 +1264,30 @@ impl BitXor for Parity {
12711264
}
12721265
}
12731266

1267+
/// Error returned when conversion from an integer to `Parity` fails.
1268+
//
1269+
// Note that we don't allow inspecting the value because we may change the type.
1270+
// Yes, this comment is intentionally NOT doc comment.
1271+
// Too many derives for compatibility with current Error type.
1272+
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)]
1273+
pub struct InvalidParityValue(i32);
1274+
1275+
impl fmt::Display for InvalidParityValue {
1276+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1277+
write!(f, "invalid value {} for Parity - must be 0 or 1", self.0)
1278+
}
1279+
}
1280+
1281+
#[cfg(feature = "std")]
1282+
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
1283+
impl ::std::error::Error for InvalidParityValue {}
1284+
1285+
impl From<InvalidParityValue> for Error {
1286+
fn from(error: InvalidParityValue) -> Self {
1287+
Error::InvalidParityValue(error)
1288+
}
1289+
}
1290+
12741291
/// The parity is serialized as `u8` - `0` for even, `1` for odd.
12751292
#[cfg(feature = "serde")]
12761293
#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]

src/lib.rs

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -361,7 +361,7 @@ pub enum Error {
361361
/// Bad set of public keys.
362362
InvalidPublicKeySum,
363363
/// The only valid parity values are 0 or 1.
364-
InvalidParityValue,
364+
InvalidParityValue(key::InvalidParityValue),
365365
}
366366

367367
impl Error {
@@ -376,7 +376,7 @@ impl Error {
376376
Error::InvalidTweak => "secp: bad tweak",
377377
Error::NotEnoughMemory => "secp: not enough memory allocated",
378378
Error::InvalidPublicKeySum => "secp: the sum of public keys was invalid or the input vector lengths was less than 1",
379-
Error::InvalidParityValue => "The only valid parity values are 0 or 1",
379+
Error::InvalidParityValue(_) => "couldn't create parity",
380380
}
381381
}
382382
}
@@ -390,7 +390,23 @@ impl fmt::Display for Error {
390390

391391
#[cfg(feature = "std")]
392392
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
393-
impl std::error::Error for Error {}
393+
impl std::error::Error for Error {
394+
#[allow(deprecated)]
395+
fn cause(&self) -> Option<&dyn std::error::Error> {
396+
match self {
397+
Error::IncorrectSignature => None,
398+
Error::InvalidMessage => None,
399+
Error::InvalidPublicKey => None,
400+
Error::InvalidSignature => None,
401+
Error::InvalidSecretKey => None,
402+
Error::InvalidRecoveryId => None,
403+
Error::InvalidTweak => None,
404+
Error::NotEnoughMemory => None,
405+
Error::InvalidPublicKeySum => None,
406+
Error::InvalidParityValue(error) => Some(error),
407+
}
408+
}
409+
}
394410

395411

396412
/// The secp256k1 engine, used to execute all signature operations.

0 commit comments

Comments
 (0)