use crate::{
BaseIter, Error, base_name,
error::{BaseEncodedError, BaseEncoderError},
prelude::Base,
};
pub trait BaseEncoder {
fn to_base_encoded(base: Base, b: &[u8]) -> String;
fn from_base_encoded(s: &str) -> Result<Vec<(Base, Vec<u8>)>, Error>;
fn debug_string(base: Base) -> String;
fn preferred_encoding(base: Base) -> Base;
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct MultibaseEncoder {}
impl BaseEncoder for MultibaseEncoder {
fn to_base_encoded(base: Base, b: &[u8]) -> String {
multi_base::encode(base, b)
}
fn from_base_encoded(s: &str) -> Result<Vec<(Base, Vec<u8>)>, Error> {
Ok(vec![
multi_base::decode(s, false).map_err(|_| BaseEncodedError::ValueFailed)?,
])
}
fn debug_string(base: Base) -> String {
format!("{} ('{}')", base_name(base), base.code())
}
fn preferred_encoding(base: Base) -> Base {
base
}
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Base58Encoder {}
impl BaseEncoder for Base58Encoder {
fn to_base_encoded(_base: Base, b: &[u8]) -> String {
Base::Base58Btc.encode(b)
}
fn from_base_encoded(s: &str) -> Result<Vec<(Base, Vec<u8>)>, Error> {
match Base::Base58Btc.decode(s, true) {
Ok(v) => Ok(vec![(Base::Base58Btc, v)]),
Err(e) => Err(BaseEncoderError::Base58(format!("{e:?}")).into()),
}
}
fn debug_string(_base: Base) -> String {
format!(
"{} ('{}')",
base_name(Base::Base58Btc),
Base::Base58Btc.code()
)
}
fn preferred_encoding(_base: Base) -> Base {
Base::Base58Btc
}
}
#[derive(Clone, Debug, Default, Eq, PartialEq)]
pub struct DetectedEncoder {}
impl BaseEncoder for DetectedEncoder {
fn to_base_encoded(base: Base, b: &[u8]) -> String {
multi_base::encode(base, b)
}
fn from_base_encoded(s: &str) -> Result<Vec<(Base, Vec<u8>)>, Error> {
if let Ok((base, data)) = multi_base::decode(s, false) {
return Ok(vec![(base, data)]);
}
let iter: BaseIter = Base::Identity.into();
for encoding in iter {
if let Ok(data) = encoding.decode(s, true) {
return Ok(vec![(encoding, data)]);
}
}
Err(BaseEncodedError::ValueFailed.into())
}
fn debug_string(base: Base) -> String {
format!("{} ('{}')", base_name(base), base.code())
}
fn preferred_encoding(base: Base) -> Base {
base
}
}