ink_codegen/generator/sol/
utils.rs1use ir::{
16 Callable,
17 InputsIter,
18 IsDocAttribute,
19 Message,
20};
21use proc_macro2::TokenStream as TokenStream2;
22use quote::{
23 quote,
24 quote_spanned,
25};
26use syn::{
27 Attribute,
28 Type,
29 spanned::Spanned,
30};
31
32pub fn sol_type(ty: &Type) -> TokenStream2 {
34 quote! {
35 <#ty as ::ink::SolDecode>::SOL_NAME
36 }
37}
38
39pub fn sol_return_type(ty: &Type) -> TokenStream2 {
47 quote! {
48 <#ty as ::ink::sol::SolResultEncode>::SOL_NAME
49 }
50}
51
52pub fn selector(message: &Message) -> TokenStream2 {
54 let name = message
55 .name()
56 .map(ToString::to_string)
57 .unwrap_or_else(|| message.ident().to_string());
58 let signature = call_signature(name, message.inputs());
59 quote! {
60 const {
61 ::ink::codegen::sol::selector_bytes(#signature)
62 }
63 }
64}
65
66pub fn selector_id(message: &Message) -> TokenStream2 {
69 let selector_bytes = selector(message);
70 quote!(
71 {
72 const {
73 ::core::primitive::u32::from_be_bytes(#selector_bytes)
74 }
75 }
76 )
77}
78
79pub fn call_signature(name: String, inputs: InputsIter) -> TokenStream2 {
81 let mut input_types_len = 0;
82 let sig_param_tys: Vec<_> = inputs
83 .map(|input| {
84 let ty = &*input.ty;
85 let sol_ty = sol_type(ty);
86 let span = input.span();
87 input_types_len += 1;
88
89 quote_spanned!(span=>
90 #sol_ty
91 )
92 })
93 .collect();
94 let sig_arg_fmt_params = (0..input_types_len)
95 .map(|_| "{}")
96 .collect::<Vec<_>>()
97 .join(",");
98 let sig_fmt_lit = format!("{{}}({sig_arg_fmt_params})");
99 quote! {
100 ::ink::codegen::utils::const_format!(#sig_fmt_lit, #name #(,#sig_param_tys)*)
101 }
102}
103
104pub fn extract_docs(attrs: &[Attribute]) -> String {
106 attrs
107 .iter()
108 .filter_map(|attr| attr.extract_docs())
109 .collect::<Vec<_>>()
110 .join("\n")
111}