sp_crypto_hashing_proc_macro/
impls.rs
1use quote::quote;
19use syn::parse::{Parse, ParseStream};
20
21use proc_macro::TokenStream;
22
23pub(super) struct InputBytes(pub Vec<u8>);
24
25pub(super) struct MultipleInputBytes(pub Vec<Vec<u8>>);
26
27impl MultipleInputBytes {
28 pub(super) fn concatenated(mut self) -> Vec<u8> {
29 if self.0.is_empty() {
30 Vec::new()
31 } else {
32 let mut result = core::mem::take(&mut self.0[0]);
33 for other in self.0[1..].iter_mut() {
34 result.append(other);
35 }
36 result
37 }
38 }
39}
40
41impl Parse for InputBytes {
42 fn parse(input: ParseStream) -> syn::Result<Self> {
43 match syn::ExprArray::parse(input) {
44 Ok(array) => {
45 let mut bytes = Vec::<u8>::new();
46 for expr in array.elems.iter() {
47 match expr {
48 syn::Expr::Lit(lit) => match &lit.lit {
49 syn::Lit::Int(b) => bytes.push(b.base10_parse()?),
50 syn::Lit::Byte(b) => bytes.push(b.value()),
51 _ =>
52 return Err(syn::Error::new(
53 input.span(),
54 "Expected array of u8 elements.".to_string(),
55 )),
56 },
57 _ =>
58 return Err(syn::Error::new(
59 input.span(),
60 "Expected array of u8 elements.".to_string(),
61 )),
62 }
63 }
64 return Ok(InputBytes(bytes))
65 },
66 Err(_e) => (),
67 }
68 match syn::Ident::parse(input) {
70 Ok(ident) => return Ok(InputBytes(ident.to_string().as_bytes().to_vec())),
71 Err(_e) => (),
72 }
73 Ok(InputBytes(syn::LitByteStr::parse(input)?.value()))
74 }
75}
76
77impl Parse for MultipleInputBytes {
78 fn parse(input: ParseStream) -> syn::Result<Self> {
79 let elts =
80 syn::punctuated::Punctuated::<InputBytes, syn::token::Comma>::parse_terminated(input)?;
81 Ok(MultipleInputBytes(elts.into_iter().map(|elt| elt.0).collect()))
82 }
83}
84
85pub(super) fn twox_64(bytes: Vec<u8>) -> TokenStream {
86 bytes_to_array(sp_crypto_hashing::twox_64(bytes.as_slice()))
87}
88
89pub(super) fn twox_128(bytes: Vec<u8>) -> TokenStream {
90 bytes_to_array(sp_crypto_hashing::twox_128(bytes.as_slice()))
91}
92
93pub(super) fn blake2b_512(bytes: Vec<u8>) -> TokenStream {
94 bytes_to_array(sp_crypto_hashing::blake2_512(bytes.as_slice()))
95}
96
97pub(super) fn blake2b_256(bytes: Vec<u8>) -> TokenStream {
98 bytes_to_array(sp_crypto_hashing::blake2_256(bytes.as_slice()))
99}
100
101pub(super) fn blake2b_64(bytes: Vec<u8>) -> TokenStream {
102 bytes_to_array(sp_crypto_hashing::blake2_64(bytes.as_slice()))
103}
104
105pub(super) fn keccak_256(bytes: Vec<u8>) -> TokenStream {
106 bytes_to_array(sp_crypto_hashing::keccak_256(bytes.as_slice()))
107}
108
109pub(super) fn keccak_512(bytes: Vec<u8>) -> TokenStream {
110 bytes_to_array(sp_crypto_hashing::keccak_512(bytes.as_slice()))
111}
112
113pub(super) fn sha2_256(bytes: Vec<u8>) -> TokenStream {
114 bytes_to_array(sp_crypto_hashing::sha2_256(bytes.as_slice()))
115}
116
117fn bytes_to_array(bytes: impl IntoIterator<Item = u8>) -> TokenStream {
118 let bytes = bytes.into_iter();
119
120 quote!(
121 [ #( #bytes ),* ]
122 )
123 .into()
124}