Skip to content

Commit b9f7462

Browse files
committed
Implement infallible for errors
Creates a new macro `impl_from_infallible`, and applies it to custom error types in the codebase. Closes rust-bitcoin#1222.
1 parent 1ac7c29 commit b9f7462

31 files changed

+165
-0
lines changed

CONTRIBUTING.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,7 @@ More specifically an error should
290290
- derive `Debug, Clone, PartialEq, Eq` (and `Copy` iff not `non_exhaustive`).
291291
- implement Display using `write_err!()` macro if a variant contains an inner error source.
292292
- have `Error` suffix
293+
- call `internals::impl_from_infallible!
293294
- implement `std::error::Error` if they are public (feature gated on "std").
294295

295296
```rust
@@ -302,6 +303,9 @@ pub enum Error {
302303
/// Documentation for variant B.
303304
B,
304305
}
306+
307+
internals::impl_from_infallible!(Error);
308+
305309
```
306310

307311

Cargo-minimal.lock

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ checksum = "08f9b8508dccb7687a1d6c4ce66b2b0ecef467c94667de27d8d7fe1f8d2a9cdc"
1212
name = "base58check"
1313
version = "0.1.0"
1414
dependencies = [
15+
"bitcoin-internals",
1516
"bitcoin_hashes",
1617
"hex-conservative",
1718
]

Cargo-recent.lock

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8"
1212
name = "base58check"
1313
version = "0.1.0"
1414
dependencies = [
15+
"bitcoin-internals",
1516
"bitcoin_hashes",
1617
"hex-conservative",
1718
]

base58/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ rustdoc-args = ["--cfg", "docsrs"]
2222

2323
[dependencies]
2424
hashes = { package = "bitcoin_hashes", version = "0.13.0", default-features = false, features = ["alloc"] }
25+
internals = { package = "bitcoin-internals", version = "0.2.0" }
2526

2627
[dev-dependencies]
2728
hex = { package = "hex-conservative", version = "0.1.1", default-features = false, features = ["alloc"] }

base58/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,8 @@ pub enum Error {
228228
TooShort(usize),
229229
}
230230

231+
internals::impl_from_infallible!(Error);
232+
231233
impl fmt::Display for Error {
232234
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
233235
use Error::*;

bitcoin/src/address/error.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ pub enum FromScriptError {
4141
WitnessVersion(witness_version::TryFromError),
4242
}
4343

44+
internals::impl_from_infallible!(FromScriptError);
45+
4446
impl fmt::Display for FromScriptError {
4547
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
4648
use FromScriptError::*;
@@ -82,6 +84,8 @@ pub enum P2shError {
8284
ExcessiveScriptSize,
8385
}
8486

87+
internals::impl_from_infallible!(P2shError);
88+
8589
impl fmt::Display for P2shError {
8690
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8791
use P2shError::*;
@@ -135,6 +139,8 @@ pub enum ParseError {
135139
UnknownHrp(UnknownHrpError),
136140
}
137141

142+
internals::impl_from_infallible!(ParseError);
143+
138144
impl fmt::Display for ParseError {
139145
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
140146
use ParseError::*;

bitcoin/src/bip152.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ pub enum Error {
2828
InvalidPrefill,
2929
}
3030

31+
internals::impl_from_infallible!(Error);
32+
3133
impl fmt::Display for Error {
3234
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3335
match *self {

bitcoin/src/bip158.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,8 @@ pub enum Error {
7777
Io(io::Error),
7878
}
7979

80+
internals::impl_from_infallible!(Error);
81+
8082
impl Display for Error {
8183
fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
8284
use Error::*;

bitcoin/src/bip32.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -491,6 +491,8 @@ pub enum Error {
491491
InvalidPublicKeyHexLength(usize),
492492
}
493493

494+
internals::impl_from_infallible!(Error);
495+
494496
impl fmt::Display for Error {
495497
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
496498
use Error::*;

bitcoin/src/blockdata/block.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -420,6 +420,8 @@ pub enum Bip34Error {
420420
NegativeHeight,
421421
}
422422

423+
internals::impl_from_infallible!(Bip34Error);
424+
423425
impl fmt::Display for Bip34Error {
424426
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
425427
use Bip34Error::*;
@@ -456,6 +458,8 @@ pub enum ValidationError {
456458
BadTarget,
457459
}
458460

461+
internals::impl_from_infallible!(ValidationError);
462+
459463
impl fmt::Display for ValidationError {
460464
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
461465
use ValidationError::*;

bitcoin/src/blockdata/locktime/absolute.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -626,6 +626,8 @@ pub enum Error {
626626
Parse(ParseIntError),
627627
}
628628

629+
internals::impl_from_infallible!(Error);
630+
629631
impl fmt::Display for Error {
630632
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
631633
use Error::*;
@@ -723,6 +725,8 @@ pub enum OperationError {
723725
InvalidComparison,
724726
}
725727

728+
internals::impl_from_infallible!(OperationError);
729+
726730
impl fmt::Display for OperationError {
727731
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
728732
use OperationError::*;
@@ -754,6 +758,8 @@ enum ParseError {
754758
Conversion(i64),
755759
}
756760

761+
internals::impl_from_infallible!(ParseError);
762+
757763
impl ParseError {
758764
fn invalid_int<S: Into<String>>(s: S) -> impl FnOnce(core::num::ParseIntError) -> Self {
759765
move |source| Self::InvalidInteger { source, input: s.into() }

bitcoin/src/blockdata/locktime/relative.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,8 @@ pub enum Error {
282282
IncompatibleTime(LockTime, Time),
283283
}
284284

285+
internals::impl_from_infallible!(Error);
286+
285287
impl fmt::Display for Error {
286288
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
287289
use Error::*;

bitcoin/src/blockdata/script/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -699,6 +699,8 @@ pub enum Error {
699699
Serialization,
700700
}
701701

702+
internals::impl_from_infallible!(Error);
703+
702704
impl fmt::Display for Error {
703705
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
704706
use Error::*;
@@ -737,6 +739,8 @@ enum UintError {
737739
NumericOverflow,
738740
}
739741

742+
internals::impl_from_infallible!(UintError);
743+
740744
impl From<UintError> for Error {
741745
fn from(error: UintError) -> Self {
742746
match error {

bitcoin/src/blockdata/script/witness_program.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,8 @@ pub enum Error {
135135
InvalidSegwitV0Length(usize),
136136
}
137137

138+
internals::impl_from_infallible!(Error);
139+
138140
impl fmt::Display for Error {
139141
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
140142
use Error::*;

bitcoin/src/blockdata/script/witness_version.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,8 @@ pub enum FromStrError {
175175
Invalid(TryFromError),
176176
}
177177

178+
internals::impl_from_infallible!(FromStrError);
179+
178180
impl fmt::Display for FromStrError {
179181
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
180182
use FromStrError::*;
@@ -216,6 +218,8 @@ pub enum TryFromInstructionError {
216218
DataPush,
217219
}
218220

221+
internals::impl_from_infallible!(TryFromInstructionError);
222+
219223
impl fmt::Display for TryFromInstructionError {
220224
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
221225
use TryFromInstructionError::*;

bitcoin/src/blockdata/transaction.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,8 @@ pub enum ParseOutPointError {
130130
VoutNotCanonical,
131131
}
132132

133+
internals::impl_from_infallible!(ParseOutPointError);
134+
133135
impl fmt::Display for ParseOutPointError {
134136
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
135137
use ParseOutPointError::*;

bitcoin/src/consensus/encode.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ pub enum Error {
6161
UnsupportedSegwitFlag(u8),
6262
}
6363

64+
internals::impl_from_infallible!(Error);
65+
6466
impl fmt::Display for Error {
6567
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6668
use Error::*;

bitcoin/src/consensus/serde.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,8 @@ enum DecodeError<E> {
368368
Other(E),
369369
}
370370

371+
internals::impl_from_infallible!(DecodeError<E>);
372+
371373
// not a trait impl because we panic on some variants
372374
fn consensus_error_into_serde<E: serde::de::Error>(error: ConsensusError) -> E {
373375
match error {

bitcoin/src/consensus/validation.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,8 @@ pub enum TxVerifyError {
209209
UnknownSpentOutput(OutPoint),
210210
}
211211

212+
internals::impl_from_infallible!(TxVerifyError);
213+
212214
impl fmt::Display for TxVerifyError {
213215
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
214216
use TxVerifyError::*;

bitcoin/src/crypto/ecdsa.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,8 @@ pub enum Error {
213213
Secp256k1(secp256k1::Error),
214214
}
215215

216+
internals::impl_from_infallible!(Error);
217+
216218
impl fmt::Display for Error {
217219
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
218220
use Error::*;

bitcoin/src/crypto/key.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -896,6 +896,8 @@ pub enum FromSliceError {
896896
InvalidLength(usize),
897897
}
898898

899+
internals::impl_from_infallible!(FromSliceError);
900+
899901
impl fmt::Display for FromSliceError {
900902
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
901903
use FromSliceError::*;
@@ -934,6 +936,8 @@ pub enum FromWifError {
934936
Secp256k1(secp256k1::Error),
935937
}
936938

939+
internals::impl_from_infallible!(FromWifError);
940+
937941
impl fmt::Display for FromWifError {
938942
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
939943
use FromWifError::*;
@@ -974,6 +978,8 @@ pub enum ParsePublicKeyError {
974978
InvalidHexLength(usize),
975979
}
976980

981+
internals::impl_from_infallible!(ParsePublicKeyError);
982+
977983
impl fmt::Display for ParsePublicKeyError {
978984
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
979985
use ParsePublicKeyError::*;
@@ -1010,6 +1016,8 @@ pub enum ParseCompressedPublicKeyError {
10101016
Hex(hex::HexToArrayError),
10111017
}
10121018

1019+
internals::impl_from_infallible!(ParseCompressedPublicKeyError);
1020+
10131021
impl fmt::Display for ParseCompressedPublicKeyError {
10141022
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
10151023
use ParseCompressedPublicKeyError::*;

bitcoin/src/crypto/sighash.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,8 @@ pub enum PrevoutsIndexError {
275275
InvalidAllIndex,
276276
}
277277

278+
internals::impl_from_infallible!(PrevoutsIndexError);
279+
278280
impl fmt::Display for PrevoutsIndexError {
279281
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
280282
use PrevoutsIndexError::*;
@@ -1151,6 +1153,8 @@ pub enum TaprootError {
11511153
InvalidSighashType(u32),
11521154
}
11531155

1156+
internals::impl_from_infallible!(TaprootError);
1157+
11541158
impl fmt::Display for TaprootError {
11551159
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
11561160
use TaprootError::*;
@@ -1208,6 +1212,8 @@ pub enum P2wpkhError {
12081212
NotP2wpkhScript,
12091213
}
12101214

1215+
internals::impl_from_infallible!(P2wpkhError);
1216+
12111217
impl From<transaction::InputsIndexError> for P2wpkhError {
12121218
fn from(value: transaction::InputsIndexError) -> Self {
12131219
P2wpkhError::Sighash(value)
@@ -1273,6 +1279,8 @@ pub enum AnnexError {
12731279
IncorrectPrefix(u8),
12741280
}
12751281

1282+
internals::impl_from_infallible!(AnnexError);
1283+
12761284
impl fmt::Display for AnnexError {
12771285
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
12781286
use AnnexError::*;
@@ -1379,6 +1387,8 @@ pub enum SigningDataError<E> {
13791387
Sighash(E),
13801388
}
13811389

1390+
internals::impl_from_infallible!(SigningDataError<E>);
1391+
13821392
impl<E> SigningDataError<E> {
13831393
/// Returns the sighash variant, panicking if it's IO.
13841394
///

bitcoin/src/crypto/taproot.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,8 @@ pub enum SigFromSliceError {
9797
InvalidSignatureSize(usize),
9898
}
9999

100+
internals::impl_from_infallible!(SigFromSliceError);
101+
100102
impl fmt::Display for SigFromSliceError {
101103
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
102104
use SigFromSliceError::*;

bitcoin/src/merkle_tree/block.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -498,6 +498,8 @@ pub enum MerkleBlockError {
498498
IdenticalHashesFound,
499499
}
500500

501+
internals::impl_from_infallible!(MerkleBlockError);
502+
501503
impl fmt::Display for MerkleBlockError {
502504
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
503505
use MerkleBlockError::*;

bitcoin/src/psbt/error.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,8 @@ pub enum Error {
103103
Io(io::Error),
104104
}
105105

106+
internals::impl_from_infallible!(Error);
107+
106108
impl fmt::Display for Error {
107109
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
108110
use Error::*;

0 commit comments

Comments
 (0)