solidity_bindgen_macros/
lib.rs

1mod abi_gen;
2
3use crate::abi_gen::abi_from_file;
4use std::env::current_dir;
5use std::fs::{metadata, read_dir};
6use std::path::Path;
7use syn::{parse_macro_input, LitStr};
8
9#[macro_use]
10extern crate quote;
11
12/// Generates a struct which allow you to call contract functions. The output
13/// struct will have the same name as the file, and have individual async
14/// methods for each contract function with parameters and output corresponding
15/// to the ABI.
16#[proc_macro]
17pub fn contract_abi(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
18    let s = parse_macro_input!(input as LitStr);
19    let path = Path::new(&current_dir().unwrap()).join(s.value());
20    let metadata = metadata(&path).unwrap();
21
22    let tokens = if metadata.is_file() {
23        abi_from_file(path)
24    } else {
25        panic!("Expected a file. To generate abis for an entire directory, use contract_abis");
26    };
27
28    tokens.into()
29}
30
31/// Generate ABIs for an entire build directory. This is the same as calling
32/// `contract_abi`for each file in the directory.
33#[proc_macro]
34pub fn contract_abis(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
35    let s = parse_macro_input!(input as LitStr);
36    let path = Path::new(&current_dir().unwrap()).join(s.value());
37    let metadata = metadata(&path).unwrap();
38
39    let tokens = if metadata.is_file() {
40        panic!("Expected a directory. To generate abis for a single file, use contract_abi");
41    } else {
42        let mut abis = Vec::new();
43        for entry in read_dir(path).unwrap() {
44            let entry = entry.unwrap();
45            if entry.metadata().unwrap().is_file() {
46                let file_abi = abi_from_file(entry.path());
47                abis.push(file_abi);
48            }
49        }
50        quote! { #(#abis)* }
51    };
52
53    tokens.into()
54}