From 7fd5e60a8bc24b2da625ba5f18f0f5cf9ade3904 Mon Sep 17 00:00:00 2001 From: Erica Marigold <hi@devcomp.xyz> Date: Sun, 15 Oct 2023 00:53:42 -0700 Subject: [PATCH] feat: reduce boilerplate using macro (thanks, dekkonot\!) --- src/lune/builtins/serde/crypto.rs | 77 +++++++++++++++++-------------- 1 file changed, 42 insertions(+), 35 deletions(-) diff --git a/src/lune/builtins/serde/crypto.rs b/src/lune/builtins/serde/crypto.rs index 46df8ad..0586251 100644 --- a/src/lune/builtins/serde/crypto.rs +++ b/src/lune/builtins/serde/crypto.rs @@ -8,18 +8,51 @@ use std::sync::Mutex; // TODO: Proper error handling, remove unwraps -#[derive(Clone)] -pub struct Crypto { - algo: Arc<Mutex<CryptoAlgo>>, +macro_rules! impl_hash_algo { + ($($algo:ident => $Type:ty),*) => { + #[derive(Clone)] + pub enum CryptoAlgo { + $( + $algo(Box<$Type>), + )* + } + + impl CryptoAlgo { + pub fn update(&mut self, data: impl AsRef<[u8]>) { + match self { + $( + Self::$algo(hasher) => hasher.update(data), + )* + } + } + + pub fn digest(&mut self, encoding: EncodingKind) -> Result<String> { + let computed = match self { + $( + Self::$algo(hasher) => hasher.clone().finalize_reset().to_vec(), + )* + }; + + match encoding { + EncodingKind::Utf8 => String::from_utf8(computed).map_err(anyhow::Error::from), + EncodingKind::Base64 => Ok(Base64::STANDARD.encode(computed)), + EncodingKind::Hex => Ok(hex::encode(&computed)), + } + } + } + } +} + +// enum CryptoAlgo +impl_hash_algo! { + Sha1 => sha1::Sha1, + Sha256 => sha2::Sha256, + Sha512 => sha2::Sha512 } #[derive(Clone)] -pub enum CryptoAlgo { - Sha1(Box<sha1::Sha1>), - Sha256(Box<sha2::Sha256>), - Sha512(Box<sha2::Sha512>), - // Blake2(Box<T>), - // Md5(Box<T>), +pub struct Crypto { + algo: Arc<Mutex<CryptoAlgo>>, } #[derive(PartialOrd, PartialEq, Ord, Eq)] @@ -67,32 +100,6 @@ impl FromLua<'_> for EncodingKind { } } -impl CryptoAlgo { - // TODO: Replace boilerplate using a macro - - pub fn update(&mut self, content: impl AsRef<[u8]>) { - match self { - CryptoAlgo::Sha1(hasher) => hasher.update(content), - CryptoAlgo::Sha256(hasher) => hasher.update(content), - CryptoAlgo::Sha512(hasher) => hasher.update(content), - }; - } - - pub fn digest(&mut self, encoding: EncodingKind) -> Result<String> { - let computed: Vec<u8> = match self { - CryptoAlgo::Sha1(hasher) => hasher.clone().finalize().to_vec(), - CryptoAlgo::Sha256(hasher) => hasher.clone().finalize().to_vec(), - CryptoAlgo::Sha512(hasher) => hasher.clone().finalize().to_vec(), - }; - - match encoding { - EncodingKind::Utf8 => String::from_utf8(computed).map_err(anyhow::Error::from), - EncodingKind::Base64 => Ok(Base64::STANDARD.encode(computed)), - EncodingKind::Hex => Ok(hex::encode(&computed)), - } - } -} - impl Crypto { pub fn sha1<T: ToString>(content: Option<T>) -> Crypto { let constructed = Self {