From 3ad89294790f7954f078cd96b05d42610fc311d0 Mon Sep 17 00:00:00 2001 From: Andrew Poelstra Date: Thu, 19 Sep 2024 14:05:31 +0000 Subject: [PATCH] correction: introduce CorrectableError trait This is just a helper trait to describe all the errors in the library from which we can get an "invalid residue". The residues contain all the information needed for error correction. --- src/primitives/correction.rs | 71 ++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/src/primitives/correction.rs b/src/primitives/correction.rs index 2d551831..7918ac8a 100644 --- a/src/primitives/correction.rs +++ b/src/primitives/correction.rs @@ -6,6 +6,12 @@ //! equation to identify the error values, in a BCH-encoded string. //! +use crate::primitives::decode::{ + CheckedHrpstringError, ChecksumError, InvalidResidueError, SegwitHrpstringError, +}; +#[cfg(feature = "alloc")] +use crate::DecodeError; + /// **One more than** the maximum length (in characters) of a checksum which /// can be error-corrected without an allocator. /// @@ -33,3 +39,68 @@ // this to 16, or maybe even higher. But we will wait for implementors who // complain. pub const NO_ALLOC_MAX_LENGTH: usize = 7; + +/// Trait describing an error for which an error correction algorithm is applicable. +/// +/// Essentially, this trait represents an error which contains an [`InvalidResidueError`] +/// variant. +pub trait CorrectableError { + /// Given a decoding error, if this is a "checksum failed" error, extract + /// that specific error type. + /// + /// There are many ways in which decoding a checksummed string might fail. + /// If the string was well-formed in all respects except that the final + /// checksum characters appear to be wrong, it is possible to run an + /// error correction algorithm to attempt to extract errors. + /// + /// In all other cases we do not have enough information to do correction. + /// + /// This is the function that implementors should implement. + fn residue_error(&self) -> Option<&InvalidResidueError>; +} + +impl CorrectableError for InvalidResidueError { + fn residue_error(&self) -> Option<&InvalidResidueError> { Some(self) } +} + +impl CorrectableError for ChecksumError { + fn residue_error(&self) -> Option<&InvalidResidueError> { + match self { + ChecksumError::InvalidResidue(ref e) => Some(e), + _ => None, + } + } +} + +impl CorrectableError for SegwitHrpstringError { + fn residue_error(&self) -> Option<&InvalidResidueError> { + match self { + SegwitHrpstringError::Checksum(ref e) => e.residue_error(), + _ => None, + } + } +} + +impl CorrectableError for CheckedHrpstringError { + fn residue_error(&self) -> Option<&InvalidResidueError> { + match self { + CheckedHrpstringError::Checksum(ref e) => e.residue_error(), + _ => None, + } + } +} + +#[cfg(feature = "alloc")] +impl CorrectableError for crate::segwit::DecodeError { + fn residue_error(&self) -> Option<&InvalidResidueError> { self.0.residue_error() } +} + +#[cfg(feature = "alloc")] +impl CorrectableError for DecodeError { + fn residue_error(&self) -> Option<&InvalidResidueError> { + match self { + DecodeError::Checksum(ref e) => e.residue_error(), + _ => None, + } + } +}