use core::convert::Infallible;
use core::fmt;
use internals::write_err;
use crate::address::{Address, NetworkUnchecked};
use crate::prelude::String;
use crate::script::{witness_program, witness_version};
use crate::Network;
#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive]
pub enum FromScriptError {
UnrecognizedScript,
WitnessProgram(witness_program::Error),
WitnessVersion(witness_version::TryFromError),
}
impl From<Infallible> for FromScriptError {
fn from(never: Infallible) -> Self {
match never {}
}
}
impl fmt::Display for FromScriptError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Self::WitnessVersion(ref e) => write_err!(f, "witness version construction error"; e),
Self::WitnessProgram(ref e) => write_err!(f, "witness program error"; e),
Self::UnrecognizedScript => write!(f, "script is not a p2pkh, p2sh or witness program"),
}
}
}
#[cfg(feature = "std")]
impl std::error::Error for FromScriptError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
Self::UnrecognizedScript => None,
Self::WitnessVersion(ref e) => Some(e),
Self::WitnessProgram(ref e) => Some(e),
}
}
}
impl From<witness_program::Error> for FromScriptError {
fn from(e: witness_program::Error) -> Self {
Self::WitnessProgram(e)
}
}
impl From<witness_version::TryFromError> for FromScriptError {
fn from(e: witness_version::TryFromError) -> Self {
Self::WitnessVersion(e)
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive]
pub struct UnknownAddressTypeError(pub String);
impl fmt::Display for UnknownAddressTypeError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write_err!(f, "failed to parse {} as address type", self.0; self)
}
}
#[cfg(feature = "std")]
impl std::error::Error for UnknownAddressTypeError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
None
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive]
pub enum ParseError {
Base58(Base58Error),
Bech32(Bech32Error),
NetworkValidation(NetworkValidationError),
}
impl From<Infallible> for ParseError {
fn from(never: Infallible) -> Self {
match never {}
}
}
impl fmt::Display for ParseError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Self::Base58(ref e) => write_err!(f, "base58 error"; e),
Self::Bech32(ref e) => write_err!(f, "bech32 error"; e),
Self::NetworkValidation(ref e) => write_err!(f, "validation error"; e),
}
}
}
#[cfg(feature = "std")]
impl std::error::Error for ParseError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
Self::Base58(ref e) => Some(e),
Self::Bech32(ref e) => Some(e),
Self::NetworkValidation(ref e) => Some(e),
}
}
}
impl From<Base58Error> for ParseError {
fn from(e: Base58Error) -> Self {
Self::Base58(e)
}
}
impl From<Bech32Error> for ParseError {
fn from(e: Bech32Error) -> Self {
Self::Bech32(e)
}
}
impl From<UnknownHrpError> for ParseError {
fn from(e: UnknownHrpError) -> Self {
Self::Bech32(e.into())
}
}
impl From<NetworkValidationError> for ParseError {
fn from(e: NetworkValidationError) -> Self {
Self::NetworkValidation(e)
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive]
pub struct UnknownHrpError(pub String);
impl fmt::Display for UnknownHrpError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "unknown hrp: {}", self.0)
}
}
#[cfg(feature = "std")]
impl std::error::Error for UnknownHrpError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
None
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive]
pub struct InvalidSegwitHrpError {
pub(crate) hrp: String,
pub(crate) expected: &'static str,
}
impl fmt::Display for InvalidSegwitHrpError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "hrp {} is only valid for {}", self.hrp, self.expected)
}
}
#[cfg(feature = "std")]
impl std::error::Error for InvalidSegwitHrpError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
None
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct NetworkValidationError {
pub(crate) required: Network,
pub(crate) address: Address<NetworkUnchecked>,
}
impl fmt::Display for NetworkValidationError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "address ")?;
fmt::Display::fmt(&self.address.inner(), f)?;
write!(f, " is not valid on {}", self.required)
}
}
#[cfg(feature = "std")]
impl std::error::Error for NetworkValidationError {}
#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive]
pub enum Bech32Error {
ParseBech32(ParseBech32Error),
WitnessVersion(witness_version::TryFromError),
WitnessProgram(witness_program::Error),
UnknownHrp(UnknownHrpError),
InvalidSegwitHrp(InvalidSegwitHrpError),
}
impl From<Infallible> for Bech32Error {
fn from(never: Infallible) -> Self {
match never {}
}
}
impl fmt::Display for Bech32Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Self::ParseBech32(ref e) => write_err!(f, "SegWit parsing error"; e),
Self::WitnessVersion(ref e) => {
write_err!(f, "witness version conversion/parsing error"; e)
}
Self::WitnessProgram(ref e) => write_err!(f, "witness program error"; e),
Self::UnknownHrp(ref e) => write_err!(f, "unknown hrp error"; e),
Self::InvalidSegwitHrp(ref e) => write_err!(f, "invalid segwit hrp"; e),
}
}
}
#[cfg(feature = "std")]
impl std::error::Error for Bech32Error {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
Self::ParseBech32(ref e) => Some(e),
Self::WitnessVersion(ref e) => Some(e),
Self::WitnessProgram(ref e) => Some(e),
Self::UnknownHrp(ref e) => Some(e),
Self::InvalidSegwitHrp(ref e) => Some(e),
}
}
}
impl From<witness_version::TryFromError> for Bech32Error {
fn from(e: witness_version::TryFromError) -> Self {
Self::WitnessVersion(e)
}
}
impl From<witness_program::Error> for Bech32Error {
fn from(e: witness_program::Error) -> Self {
Self::WitnessProgram(e)
}
}
impl From<UnknownHrpError> for Bech32Error {
fn from(e: UnknownHrpError) -> Self {
Self::UnknownHrp(e)
}
}
impl From<InvalidSegwitHrpError> for Bech32Error {
fn from(e: InvalidSegwitHrpError) -> Self {
Self::InvalidSegwitHrp(e)
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ParseBech32Error(pub(crate) bech32::segwit::DecodeError);
impl From<Infallible> for ParseBech32Error {
fn from(never: Infallible) -> Self {
match never {}
}
}
impl fmt::Display for ParseBech32Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write_err!(f, "bech32 parsing error"; self.0)
}
}
#[cfg(feature = "std")]
impl std::error::Error for ParseBech32Error {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
Some(&self.0)
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive]
pub enum Base58Error {
ParseBase58(base58::Error),
LegacyAddressTooLong(LegacyAddressTooLongError),
InvalidBase58PayloadLength(InvalidBase58PayloadLengthError),
InvalidLegacyPrefix(InvalidLegacyPrefixError),
}
impl From<Infallible> for Base58Error {
fn from(never: Infallible) -> Self {
match never {}
}
}
impl fmt::Display for Base58Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Self::ParseBase58(ref e) => write_err!(f, "legacy parsing error"; e),
Self::LegacyAddressTooLong(ref e) => write_err!(f, "legacy address length error"; e),
Self::InvalidBase58PayloadLength(ref e) => {
write_err!(f, "legacy payload length error"; e)
}
Self::InvalidLegacyPrefix(ref e) => write_err!(f, "legacy prefix error"; e),
}
}
}
#[cfg(feature = "std")]
impl std::error::Error for Base58Error {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
Self::ParseBase58(ref e) => Some(e),
Self::LegacyAddressTooLong(ref e) => Some(e),
Self::InvalidBase58PayloadLength(ref e) => Some(e),
Self::InvalidLegacyPrefix(ref e) => Some(e),
}
}
}
impl From<base58::Error> for Base58Error {
fn from(e: base58::Error) -> Self {
Self::ParseBase58(e)
}
}
impl From<LegacyAddressTooLongError> for Base58Error {
fn from(e: LegacyAddressTooLongError) -> Self {
Self::LegacyAddressTooLong(e)
}
}
impl From<InvalidBase58PayloadLengthError> for Base58Error {
fn from(e: InvalidBase58PayloadLengthError) -> Self {
Self::InvalidBase58PayloadLength(e)
}
}
impl From<InvalidLegacyPrefixError> for Base58Error {
fn from(e: InvalidLegacyPrefixError) -> Self {
Self::InvalidLegacyPrefix(e)
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct InvalidBase58PayloadLengthError {
pub(crate) length: usize,
}
impl InvalidBase58PayloadLengthError {
pub fn invalid_base58_payload_length(&self) -> usize {
self.length
}
}
impl fmt::Display for InvalidBase58PayloadLengthError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "decoded base58 data was an invalid length: {} (expected 21)", self.length)
}
}
#[cfg(feature = "std")]
impl std::error::Error for InvalidBase58PayloadLengthError {}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct LegacyAddressTooLongError {
pub(crate) length: usize,
}
impl LegacyAddressTooLongError {
pub fn invalid_legacy_address_length(&self) -> usize {
self.length
}
}
impl fmt::Display for LegacyAddressTooLongError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "legacy address is too long: {} (max 50 characters)", self.length)
}
}
#[cfg(feature = "std")]
impl std::error::Error for LegacyAddressTooLongError {}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct InvalidLegacyPrefixError {
pub(crate) invalid: u8,
}
impl InvalidLegacyPrefixError {
pub fn invalid_legacy_address_prefix(&self) -> u8 {
self.invalid
}
}
impl fmt::Display for InvalidLegacyPrefixError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "invalid legacy address prefix in decoded base58 data {}", self.invalid)
}
}
#[cfg(feature = "std")]
impl std::error::Error for InvalidLegacyPrefixError {}