otp_std/secret/
encoding.rs1use base32::Alphabet;
4use miette::Diagnostic;
5use thiserror::Error;
6
7use crate::macros::errors;
8
9#[derive(Debug, Error, Diagnostic)]
11#[error("failed to decode `{secret}` secret")]
12#[diagnostic(code(otp_std::secret::encoding), help("make sure the secret is valid"))]
13pub struct Error {
14 pub secret: String,
16}
17
18impl Error {
19 pub const fn new(secret: String) -> Self {
21 Self { secret }
22 }
23}
24
25pub const ALPHABET: Alphabet = Alphabet::Rfc4648 { padding: false };
27
28pub fn encode<S: AsRef<[u8]>>(secret: S) -> String {
30 base32::encode(ALPHABET, secret.as_ref())
31}
32
33errors! {
34 Type = Error,
35 Hack = $,
36 error => new(secret => to_owned),
37}
38
39pub fn decode<S: AsRef<str>>(secret: S) -> Result<Vec<u8>, Error> {
45 fn decode_inner(secret: &str) -> Result<Vec<u8>, Error> {
46 base32::decode(ALPHABET, secret).ok_or_else(|| error!(secret))
47 }
48
49 decode_inner(secret.as_ref())
50}