ultimate-common 0.1.0

Rust libraries
Documentation
use base64ct::{Base64UrlUnpadded, Encoding};
pub use hmac::digest::InvalidLength;
use hmac::{
  digest::{
    generic_array::GenericArray,
    typenum::{UInt, UTerm, B0, B1},
    CtOutput,
  },
  Hmac, Mac,
};
use sha2::{Digest, Sha256};

use crate::Error;

type HmacSha256 = Hmac<Sha256>;

pub fn hmac_sha256(secret: &[u8], s: &[u8]) -> Result<CtOutput<HmacSha256>, InvalidLength> {
  let mut mac = HmacSha256::new_from_slice(secret)?;
  mac.update(s);
  let result = mac.finalize();
  Ok(result)
}

#[inline]
pub fn hmac_sha256_string(secret: &[u8], s: &[u8]) -> Result<String, InvalidLength> {
  let bytes = hmac_sha256(secret, s)?.into_bytes();
  Ok(base16ct::lower::encode_string(&bytes))
}

type ShaArray = GenericArray<u8, UInt<UInt<UInt<UInt<UInt<UInt<UTerm, B1>, B0>, B0>, B0>, B0>, B0>>;

pub fn sha256(s: &[u8]) -> ShaArray {
  let mut hasher: Sha256 = Sha256::new();
  hasher.update(s);
  hasher.finalize()
}

#[inline]
pub fn sha256_string(s: &[u8]) -> String {
  let result = sha256(s);
  base16ct::lower::encode_string(&result)
}

pub fn b64u_encode(content: impl AsRef<[u8]>) -> String {
  Base64UrlUnpadded::encode_string(content.as_ref())
}

pub fn b64u_decode(b64u: &str) -> Result<Vec<u8>, Error> {
  Base64UrlUnpadded::decode_vec(b64u).map_err(|_| Error::FailToB64uDecode(b64u.to_string()))
}

pub fn b64u_decode_to_string(b64u: &str) -> Result<String, Error> {
  b64u_decode(b64u).ok().and_then(|r| String::from_utf8(r).ok()).ok_or(Error::FailToB64uDecode(b64u.to_string()))
}