commit f4aaa2a3d5015998751e1f73f9ba8d5545421808 Author: Jessie Date: Sun Aug 27 20:12:47 2023 -0400 init diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4fffb2f --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/target +/Cargo.lock diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..06806c4 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "prochash" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[lib] +proc-macro = true + +[dependencies] +quote = "1" +proc-macro2 = "1.0" +syn = { version = "2.0.28", features = ["full"] } +k12 = "0.3.0" \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..3227bb0 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,84 @@ +use syn::{parse_macro_input, Expr, Lit}; +use proc_macro::{TokenStream}; +use proc_macro2::Literal; +use k12::{digest:: *}; +use quote::ToTokens; + + +fn _hashTokenStream>(input: TokenStream, conversion_func: F) -> TokenStream { + let expr = parse_macro_input!(input as Expr); + + let string = match &expr { + Expr::Lit(literal) => { + match &literal.lit { + Lit::Str(s) => {Some(s.value())} + _ => {None} + } + } + _ => { None } + }; + + let string = string.unwrap_or_else(|| expr.to_token_stream().to_string()); + + let mut hasher = k12::KangarooTwelve::default(); + hasher.update(string.as_bytes()); + let bytes = hasher.finalize_boxed(8); + let u64 = { + let mut b = [0u8;8]; + b.copy_from_slice(bytes.as_ref()); + u64::from_le_bytes(b) + }; + conversion_func(u64) +} + + +#[proc_macro] +pub fn u64(input: TokenStream) -> TokenStream { + _hash(input, |value| { + Literal::u64_suffixed(value).to_token_stream().into() + }) +} + +#[proc_macro] +pub fn u64s(input: TokenStream) -> TokenStream { + _hash(input, |value| { + let value = format!("{:016X}", value); + Literal::string(&value).to_token_stream().into() + }) +} + +#[proc_macro] +pub fn u32(input: TokenStream) -> TokenStream { + _hash(input, |value| { + let value = (value as u32) ^ (value >> 32) as u32; + Literal::u32_suffixed(value).to_token_stream().into() + }) +} + +#[proc_macro] +pub fn u32s(input: TokenStream) -> TokenStream { + _hash(input, |value| { + let value = (value as u32) ^ (value >> 32) as u32; + let value = format!("{:08X}", value); + Literal::string(&value).to_token_stream().into() + }) +} + +#[proc_macro] +pub fn u16(input: TokenStream) -> TokenStream { + _hash(input, |value| { + let value = (value as u32) ^ (value >> 32) as u32; + let value = value as u16 ^ (value >> 16) as u16; + Literal::u16_suffixed(value).to_token_stream().into() + }) +} + +#[proc_macro] +pub fn u16s(input: TokenStream) -> TokenStream { + _hash(input, |value| { + let value = (value as u32) ^ (value >> 32) as u32; + let value = value as u16 ^ (value >> 16) as u16; + let value = format!("{:04X}", value); + Literal::string(&value).to_token_stream().into() + }) +} \ No newline at end of file diff --git a/tests/test.rs b/tests/test.rs new file mode 100644 index 0000000..91d4542 --- /dev/null +++ b/tests/test.rs @@ -0,0 +1,6 @@ + +#[test] +pub fn test() { + let a = prochash::u32s!("Hello Hash!"); + println!("a: {a}"); +} \ No newline at end of file