precompile_utils_macro/
lib.rs

1// This file is part of Frontier.
2
3// Copyright (c) Moonsong Labs.
4// Copyright (C) Parity Technologies (UK) Ltd.
5// SPDX-License-Identifier: Apache-2.0
6
7// Licensed under the Apache License, Version 2.0 (the "License");
8// you may not use this file except in compliance with the License.
9// You may obtain a copy of the License at
10//
11// 	http://www.apache.org/licenses/LICENSE-2.0
12//
13// Unless required by applicable law or agreed to in writing, software
14// distributed under the License is distributed on an "AS IS" BASIS,
15// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16// See the License for the specific language governing permissions and
17// limitations under the License.
18
19#![crate_type = "proc-macro"]
20extern crate proc_macro;
21
22use proc_macro::TokenStream;
23use quote::{quote, quote_spanned};
24use sp_crypto_hashing::keccak_256;
25use syn::{parse_macro_input, spanned::Spanned, Expr, Ident, ItemType, Lit, LitStr};
26
27mod derive_codec;
28mod precompile;
29mod precompile_name_from_address;
30
31struct Bytes(Vec<u8>);
32
33impl ::std::fmt::Debug for Bytes {
34	#[inline]
35	fn fmt(&self, f: &mut std::fmt::Formatter) -> ::std::fmt::Result {
36		let data = &self.0;
37		write!(f, "[")?;
38		if !data.is_empty() {
39			write!(f, "{:#04x}u8", data[0])?;
40			for unit in data.iter().skip(1) {
41				write!(f, ", {unit:#04x}")?;
42			}
43		}
44		write!(f, "]")
45	}
46}
47
48#[proc_macro]
49pub fn keccak256(input: TokenStream) -> TokenStream {
50	let lit_str = parse_macro_input!(input as LitStr);
51
52	let hash = keccak_256(lit_str.value().as_bytes());
53
54	let bytes = Bytes(hash.to_vec());
55	let eval_str = format!("{bytes:?}");
56	let eval_ts: proc_macro2::TokenStream = eval_str.parse().unwrap_or_else(|_| {
57		panic!("Failed to parse the string \"{eval_str}\" to TokenStream.");
58	});
59	quote!(#eval_ts).into()
60}
61
62#[proc_macro_attribute]
63pub fn precompile(attr: TokenStream, input: TokenStream) -> TokenStream {
64	precompile::main(attr, input)
65}
66
67#[proc_macro_attribute]
68pub fn precompile_name_from_address(attr: TokenStream, input: TokenStream) -> TokenStream {
69	precompile_name_from_address::main(attr, input)
70}
71
72#[proc_macro_derive(Codec)]
73pub fn derive_codec(input: TokenStream) -> TokenStream {
74	derive_codec::main(input)
75}