1use cainome_parser::{AbiParser, AbiParserLegacy};
2use cainome_rs::{self};
3use proc_macro::TokenStream;
4use proc_macro_error::proc_macro_error;
5use quote::quote;
6
7mod macro_inputs;
8mod macro_inputs_legacy;
9mod spanned;
10
11use crate::macro_inputs::ContractAbi;
12use crate::macro_inputs_legacy::ContractAbiLegacy;
13
14#[proc_macro_error]
15#[proc_macro]
16pub fn abigen(input: TokenStream) -> TokenStream {
17 abigen_internal(input)
18}
19
20#[proc_macro_error]
21#[proc_macro]
22pub fn abigen_legacy(input: TokenStream) -> TokenStream {
23 abigen_internal_legacy(input)
24}
25
26fn abigen_internal(input: TokenStream) -> TokenStream {
27 let contract_abi = syn::parse_macro_input!(input as ContractAbi);
28
29 let abi_entries = contract_abi.abi;
30 let contract_name = contract_abi.name;
31
32 let abi_tokens = AbiParser::collect_tokens(&abi_entries, &contract_abi.type_aliases)
33 .expect("failed tokens parsing");
34
35 let expanded = cainome_rs::abi_to_tokenstream(
36 &contract_name.to_string(),
37 &abi_tokens,
38 contract_abi.execution_version,
39 &contract_abi.derives,
40 &contract_abi.contract_derives,
41 &contract_abi.type_skips,
42 );
43
44 if let Some(out_path) = contract_abi.output_path {
45 let content: String = expanded.to_string();
46 match std::fs::write(out_path, content) {
47 Ok(_) => (),
48 Err(e) => panic!("Failed to write to file: {}", e),
49 }
50
51 quote!().into()
52 } else {
53 expanded.into()
54 }
55}
56
57fn abigen_internal_legacy(input: TokenStream) -> TokenStream {
58 let contract_abi = syn::parse_macro_input!(input as ContractAbiLegacy);
59
60 let abi_entries = contract_abi.abi;
61 let contract_name = contract_abi.name;
62
63 let abi_tokens = AbiParserLegacy::collect_tokens(&abi_entries, &contract_abi.type_aliases)
64 .expect("failed tokens parsing");
65
66 let expanded = cainome_rs::abi_to_tokenstream(
67 &contract_name.to_string(),
68 &abi_tokens,
69 contract_abi.execution_version,
70 &contract_abi.derives,
71 &contract_abi.contract_derives,
72 &contract_abi.type_skips,
73 );
74
75 if let Some(out_path) = contract_abi.output_path {
76 let content: String = expanded.to_string();
77 match std::fs::write(out_path, content) {
78 Ok(_) => (),
79 Err(e) => panic!("Failed to write to file: {}", e),
80 }
81
82 quote!().into()
83 } else {
84 expanded.into()
85 }
86}