odra_codegen/generator/module_impl/
reference.rs1use derive_more::From;
2use odra_ir::module::{Constructor, Method, ModuleImpl};
3use proc_macro2::TokenStream;
4use quote::{format_ident, quote};
5
6use crate::{
7 generator::common::{self, build_ref},
8 GenerateCode
9};
10
11#[derive(From)]
12pub struct ContractReference<'a> {
13 contract: &'a ModuleImpl
14}
15
16as_ref_for_contract_impl_generator!(ContractReference);
17
18impl GenerateCode for ContractReference<'_> {
19 fn generate_code(&self) -> TokenStream {
20 let struct_ident = self.contract.ident();
21 let ref_ident = format_ident!("{}Ref", struct_ident);
22
23 let ref_entrypoints = build_entrypoints(self.contract.get_public_method_iter());
24
25 let ref_constructors = build_constructors(self.contract.get_constructor_iter());
26
27 let contract_ref = build_ref(&ref_ident, struct_ident);
28
29 quote! {
30 #contract_ref
31
32 impl #ref_ident {
33 #ref_entrypoints
34
35 #ref_constructors
36 }
37 }
38 }
39}
40fn build_entrypoints<'a, T>(methods: T) -> TokenStream
42where
43 T: Iterator<Item = &'a Method>
44{
45 methods
46 .map(|entrypoint| {
47 let attrs = &entrypoint.impl_item.attrs;
48 let sig = &entrypoint.full_sig;
49 let entrypoint_name = &entrypoint.ident.to_string();
50 let fn_body =
51 common::generate_fn_body(entrypoint.args.clone(), entrypoint_name, &entrypoint.ret);
52
53 quote! {
54 #(#attrs)*
55 pub #sig {
56 #fn_body
57 }
58 }
59 })
60 .collect::<TokenStream>()
61}
62
63fn build_constructors<'a, T>(constructors: T) -> TokenStream
64where
65 T: Iterator<Item = &'a Constructor>
66{
67 constructors
68 .map(|constructor| {
69 let attrs = &constructor.impl_item.attrs;
70 let sig = &constructor.full_sig;
71 let constructor_name = constructor.ident.to_string();
72 let fn_body = common::generate_fn_body(
73 constructor.args.clone(),
74 &constructor_name,
75 &syn::ReturnType::Default
76 );
77
78 quote! {
79 #(#attrs)*
80 pub #sig {
81 #fn_body
82 }
83 }
84 })
85 .collect::<TokenStream>()
86}