1use proc_macro2::TokenStream as TokenStream2;
16use syn::spanned::Spanned as _;
17
18pub fn blake2b_256(input: &[u8], output: &mut [u8; 32]) {
20 use ::blake2::digest::{
21 consts::U32,
22 Digest as _,
23 };
24
25 type Blake2b256 = ::blake2::Blake2b<U32>;
26
27 let mut blake2 = Blake2b256::new();
28 blake2.update(input);
29 let result = blake2.finalize();
30 output.copy_from_slice(&result);
31}
32
33#[derive(Debug)]
39pub struct Blake2x256Macro {
40 hash: [u8; 32],
41 input: syn::Lit,
42}
43
44impl Blake2x256Macro {
45 pub fn hash(&self) -> [u8; 32] {
47 self.hash
48 }
49
50 pub fn input(&self) -> &syn::Lit {
52 &self.input
53 }
54}
55
56impl TryFrom<TokenStream2> for Blake2x256Macro {
57 type Error = syn::Error;
58
59 fn try_from(input: TokenStream2) -> Result<Self, Self::Error> {
60 let input_span = input.span();
61 let lit = syn::parse2::<syn::Lit>(input).map_err(|error| {
62 format_err!(
63 input_span,
64 "expected string or byte string literal as input: {}",
65 error
66 )
67 })?;
68 let input_bytes = match lit {
69 syn::Lit::Str(ref lit_str) => lit_str.value().into_bytes(),
70 syn::Lit::ByteStr(ref byte_str) => byte_str.value(),
71 invalid => {
72 return Err(format_err!(
73 invalid.span(),
74 "expected string or byte string literal as input. found {:?}",
75 invalid,
76 ))
77 }
78 };
79 let mut output = [0u8; 32];
80 blake2b_256(&input_bytes, &mut output);
81 Ok(Self {
82 hash: output,
83 input: lit,
84 })
85 }
86}