use core::convert::Infallible;
use core::fmt;
use internals::write_err;
#[cfg(feature = "alloc")]
#[deprecated(since = "TBD", note = "use DecodeCheckError instead")]
pub type Error = DecodeCheckError;
#[cfg(feature = "alloc")]
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct DecodeCheckError(pub(super) DecodeCheckErrorInner);
#[cfg(not(feature = "alloc"))]
#[derive(Debug, Clone, PartialEq, Eq)]
pub(crate) struct DecodeCheckError(pub(super) DecodeCheckErrorInner);
#[derive(Debug, Clone, PartialEq, Eq)]
pub(super) enum DecodeCheckErrorInner {
Decode(InvalidCharacterError),
IncorrectChecksum(IncorrectChecksumError),
TooShort(TooShortError),
}
impl DecodeCheckError {
pub fn invalid_character(&self) -> Option<u8> {
match self.0 {
DecodeCheckErrorInner::Decode(ref e) => Some(e.invalid_character()),
_ => None,
}
}
pub fn incorrect_checksum(&self) -> Option<(u32, u32)> {
match self.0 {
DecodeCheckErrorInner::IncorrectChecksum(ref e) => Some((e.incorrect, e.expected)),
_ => None,
}
}
pub fn invalid_length(&self) -> Option<usize> {
match self.0 {
DecodeCheckErrorInner::TooShort(ref e) => Some(e.length),
_ => None,
}
}
}
impl From<Infallible> for DecodeCheckError {
fn from(never: Infallible) -> Self { match never {} }
}
impl fmt::Display for DecodeCheckError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use DecodeCheckErrorInner::{Decode, IncorrectChecksum, TooShort};
match self.0 {
Decode(ref e) => write_err!(f, "decode"; e),
IncorrectChecksum(ref e) => write_err!(f, "incorrect checksum"; e),
TooShort(ref e) => write_err!(f, "too short"; e),
}
}
}
#[cfg(feature = "std")]
impl std::error::Error for DecodeCheckError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
use DecodeCheckErrorInner::{Decode, IncorrectChecksum, TooShort};
match self.0 {
Decode(ref e) => Some(e),
IncorrectChecksum(ref e) => Some(e),
TooShort(ref e) => Some(e),
}
}
}
impl From<InvalidCharacterError> for DecodeCheckError {
fn from(e: InvalidCharacterError) -> Self { Self(DecodeCheckErrorInner::Decode(e)) }
}
impl From<IncorrectChecksumError> for DecodeCheckError {
fn from(e: IncorrectChecksumError) -> Self { Self(DecodeCheckErrorInner::IncorrectChecksum(e)) }
}
impl From<TooShortError> for DecodeCheckError {
fn from(e: TooShortError) -> Self { Self(DecodeCheckErrorInner::TooShort(e)) }
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub(super) struct IncorrectChecksumError {
pub(super) incorrect: u32,
pub(super) expected: u32,
}
impl From<Infallible> for IncorrectChecksumError {
fn from(never: Infallible) -> Self { match never {} }
}
impl fmt::Display for IncorrectChecksumError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"base58 checksum {:#x} does not match expected {:#x}",
self.incorrect, self.expected
)
}
}
#[cfg(feature = "std")]
impl std::error::Error for IncorrectChecksumError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
let Self { incorrect: _, expected: _ } = self;
None
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub(super) struct TooShortError {
pub(super) length: usize,
}
impl From<Infallible> for TooShortError {
fn from(never: Infallible) -> Self { match never {} }
}
impl fmt::Display for TooShortError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"base58 decoded data was not long enough, must be at least 4 bytes: {}",
self.length
)
}
}
#[cfg(feature = "std")]
impl std::error::Error for TooShortError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
let Self { length: _ } = self;
None
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct InputTooLongError(pub(super) InputTooLongErrorInner);
#[derive(Debug, Clone, PartialEq, Eq)]
pub(super) struct InputTooLongErrorInner {
pub(super) input_len: usize,
}
impl InputTooLongError {
pub fn input_length(&self) -> usize { self.0.input_len }
}
impl From<Infallible> for InputTooLongError {
fn from(never: Infallible) -> Self { match never {} }
}
impl fmt::Display for InputTooLongError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"base58check encoding of {} bytes of data exceeds the 128 character buffer",
self.0.input_len
)
}
}
#[cfg(feature = "std")]
impl std::error::Error for InputTooLongError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
let InputTooLongErrorInner { input_len: _ } = self.0;
None
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct DecodeCheckArrayError(pub(super) DecodeCheckArrayErrorInner);
#[derive(Debug, Clone, PartialEq, Eq)]
pub(super) enum DecodeCheckArrayErrorInner {
Decode(DecodeCheckError),
UnexpectedLength(UnexpectedLengthError),
}
impl DecodeCheckArrayError {
pub fn invalid_character(&self) -> Option<u8> {
match self.0 {
DecodeCheckArrayErrorInner::Decode(ref e) => e.invalid_character(),
DecodeCheckArrayErrorInner::UnexpectedLength(_) => None,
}
}
pub fn incorrect_checksum(&self) -> Option<(u32, u32)> {
match self.0 {
DecodeCheckArrayErrorInner::Decode(ref e) => e.incorrect_checksum(),
DecodeCheckArrayErrorInner::UnexpectedLength(_) => None,
}
}
pub fn invalid_length(&self) -> Option<usize> {
match self.0 {
DecodeCheckArrayErrorInner::Decode(ref e) => e.invalid_length(),
DecodeCheckArrayErrorInner::UnexpectedLength(_) => None,
}
}
}
impl From<Infallible> for DecodeCheckArrayError {
fn from(never: Infallible) -> Self { match never {} }
}
impl fmt::Display for DecodeCheckArrayError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use DecodeCheckArrayErrorInner::{Decode, UnexpectedLength};
match self.0 {
Decode(ref e) => write_err!(f, "decode"; e),
UnexpectedLength(ref e) => write_err!(f, "unexpected length"; e),
}
}
}
#[cfg(feature = "std")]
impl std::error::Error for DecodeCheckArrayError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
use DecodeCheckArrayErrorInner::{Decode, UnexpectedLength};
match self.0 {
Decode(ref e) => Some(e),
UnexpectedLength(ref e) => Some(e),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub(super) struct UnexpectedLengthError {
pub(super) expected: usize,
pub(super) actual: usize,
}
impl From<Infallible> for UnexpectedLengthError {
fn from(never: Infallible) -> Self { match never {} }
}
impl fmt::Display for UnexpectedLengthError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"decoded base58check payload was {} bytes, expected {}",
self.actual, self.expected
)
}
}
#[cfg(feature = "std")]
impl std::error::Error for UnexpectedLengthError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
let Self { expected: _, actual: _ } = self;
None
}
}
#[cfg(feature = "alloc")]
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct InvalidCharacterError(pub(super) InvalidCharacterErrorInner);
#[cfg(not(feature = "alloc"))]
#[derive(Debug, Clone, PartialEq, Eq)]
pub(crate) struct InvalidCharacterError(pub(super) InvalidCharacterErrorInner);
#[derive(Debug, Clone, PartialEq, Eq)]
pub(super) struct InvalidCharacterErrorInner {
pub(super) invalid: u8,
}
impl InvalidCharacterError {
pub(super) fn new(invalid: u8) -> Self { Self(InvalidCharacterErrorInner { invalid }) }
pub fn invalid_character(&self) -> u8 { self.0.invalid }
}
impl From<Infallible> for InvalidCharacterError {
fn from(never: Infallible) -> Self { match never {} }
}
impl fmt::Display for InvalidCharacterError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "invalid base58 character {:#x}", self.0.invalid)
}
}
#[cfg(feature = "std")]
impl std::error::Error for InvalidCharacterError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
let Self(_) = self;
None
}
}
pub(super) enum Base256Error<T> {
Buffer(T),
InvalidChar(InvalidCharacterError),
}