pub use data_encoding::{DecodeError, DecodeKind};
use hex::FromHexError;
pub fn fmt(bytes: impl AsRef<[u8]>) -> String {
let mut text = data_encoding::BASE32_NOPAD.encode(bytes.as_ref());
text.make_ascii_lowercase();
text
}
pub fn fmt_append(bytes: impl AsRef<[u8]>, out: &mut String) {
let start = out.len();
data_encoding::BASE32_NOPAD.encode_append(bytes.as_ref(), out);
let end = out.len();
out[start..end].make_ascii_lowercase();
}
pub fn fmt_short(bytes: impl AsRef<[u8]>) -> String {
let len = bytes.as_ref().len().min(10);
let mut text = data_encoding::BASE32_NOPAD.encode(&bytes.as_ref()[..len]);
text.make_ascii_lowercase();
text
}
pub fn parse_array<const N: usize>(input: &str) -> Result<[u8; N], DecodeError> {
data_encoding::BASE32_NOPAD
.decode(input.to_ascii_uppercase().as_bytes())?
.try_into()
.map_err(|_| DecodeError {
position: N,
kind: DecodeKind::Length,
})
}
pub fn parse_vec(input: &str) -> Result<Vec<u8>, DecodeError> {
data_encoding::BASE32_NOPAD.decode(input.to_ascii_uppercase().as_bytes())
}
#[derive(thiserror::Error, Debug)]
pub enum HexOrBase32ParseError {
#[error("base32: {0}")]
Base32(#[from] data_encoding::DecodeError),
#[error("hex: {0}")]
Hex(#[from] FromHexError),
}
pub fn parse_array_hex_or_base32<const LEN: usize>(
input: &str,
) -> std::result::Result<[u8; LEN], HexOrBase32ParseError> {
let mut bytes = [0u8; LEN];
if input.len() == LEN * 2 {
hex::decode_to_slice(input, &mut bytes)?;
Ok(bytes)
} else {
Ok(parse_array(input)?)
}
}