referrerpolicy=no-referrer-when-downgrade

sp_crypto_hashing_proc_macro/
impls.rs

1// This file is part of Substrate.
2
3// Copyright (C) Parity Technologies (UK) Ltd.
4// SPDX-License-Identifier: Apache-2.0
5
6// Licensed under the Apache License, Version 2.0 (the "License");
7// you may not use this file except in compliance with the License.
8// You may obtain a copy of the License at
9//
10// 	http://www.apache.org/licenses/LICENSE-2.0
11//
12// Unless required by applicable law or agreed to in writing, software
13// distributed under the License is distributed on an "AS IS" BASIS,
14// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15// See the License for the specific language governing permissions and
16// limitations under the License.
17
18use 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		// use rust names as a vec of their utf8 bytecode.
69		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}