use std::error::Error;
use std::fmt;
use crate::base_n::{BaseNDecodeError, decode_base_n, encode_base_n};
const BITCOIN_BASE58_ALPHABET: &[u8] =
b"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[non_exhaustive]
pub enum Base58DecodeError {
InvalidCharacter {
index: usize,
byte: u8,
},
}
impl fmt::Display for Base58DecodeError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::InvalidCharacter { index, byte } => {
write!(
f,
"base58 input contains invalid byte 0x{byte:02x} at position {index}"
)
}
}
}
}
impl Error for Base58DecodeError {}
impl From<BaseNDecodeError> for Base58DecodeError {
fn from(error: BaseNDecodeError) -> Self {
match error {
BaseNDecodeError::InvalidCharacter { index, byte } => {
Self::InvalidCharacter { index, byte }
}
}
}
}
#[must_use]
pub fn encode_base58(bytes: impl AsRef<[u8]>) -> String {
encode_base_n(bytes.as_ref(), BITCOIN_BASE58_ALPHABET)
}
pub fn decode_base58(encoded: impl AsRef<str>) -> Result<Vec<u8>, Base58DecodeError> {
decode_base_n(encoded.as_ref(), BITCOIN_BASE58_ALPHABET).map_err(Into::into)
}