use base32::Alphabet;
use miette::Diagnostic;
use thiserror::Error;
use crate::macros::errors;
#[derive(Debug, Error, Diagnostic)]
#[error("failed to decode `{secret}` secret")]
#[diagnostic(code(otp_std::secret::encoding), help("make sure the secret is valid"))]
pub struct Error {
pub secret: String,
}
impl Error {
pub const fn new(secret: String) -> Self {
Self { secret }
}
}
pub const ALPHABET: Alphabet = Alphabet::Rfc4648 { padding: false };
pub fn encode<S: AsRef<[u8]>>(secret: S) -> String {
base32::encode(ALPHABET, secret.as_ref())
}
errors! {
Type = Error,
Hack = $,
error => new(secret => to_owned),
}
pub fn decode<S: AsRef<str>>(secret: S) -> Result<Vec<u8>, Error> {
fn decode_inner(secret: &str) -> Result<Vec<u8>, Error> {
base32::decode(ALPHABET, secret).ok_or_else(|| error!(secret))
}
decode_inner(secret.as_ref())
}