use super::{util, Context}; use ethers_core::types::Address; use proc_macro2::{Literal, TokenStream}; use quote::quote; pub(crate) fn imports(name: &str) -> TokenStream { let doc = util::expand_doc(&format!("{} was auto-generated with ethers-rs Abigen. More information at: https://github.com/gakonst/ethers-rs", name)); quote! { #![allow(dead_code)] #![allow(unused_imports)] #doc use std::sync::Arc; use ethers::{ core::{ abi::{Abi, Token, Detokenize, InvalidOutputType, Tokenizable, parse_abi}, types::*, // import all the types so that we can codegen for everything }, contract::{Contract, builders::{ContractCall, Event}, Lazy}, providers::Middleware, }; } } pub(crate) fn struct_declaration(cx: &Context, abi_name: &proc_macro2::Ident) -> TokenStream { let name = &cx.contract_name; let abi = &cx.abi_str; let abi_parse = if !cx.human_readable { quote! { pub static #abi_name: Lazy = Lazy::new(|| serde_json::from_str(#abi) .expect("invalid abi")); } } else { quote! { pub static #abi_name: Lazy = Lazy::new(|| { let abi_str = #abi.replace('[', "").replace(']', ""); // split lines and get only the non-empty things let split: Vec<&str> = abi_str .split("\n") .map(|x| x.trim()) .filter(|x| !x.is_empty()) .collect(); parse_abi(&split).expect("invalid abi") }); } }; quote! { // Inline ABI declaration #abi_parse // Struct declaration #[derive(Clone)] pub struct #name(Contract); // Deref to the inner contract in order to access more specific functions functions impl std::ops::Deref for #name { type Target = Contract; fn deref(&self) -> &Self::Target { &self.0 } } impl std::fmt::Debug for #name { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { f.debug_tuple(stringify!(#name)) .field(&self.address()) .finish() } } } }