anchor_syn/codegen/accounts/
mod.rs1use crate::AccountsStruct;
2use quote::quote;
3use std::iter;
4use syn::punctuated::Punctuated;
5use syn::{ConstParam, LifetimeDef, Token, TypeParam};
6use syn::{GenericParam, PredicateLifetime, WhereClause, WherePredicate};
7
8pub mod __client_accounts;
9pub mod __cpi_client_accounts;
10mod bumps;
11mod constraints;
12mod exit;
13mod to_account_infos;
14mod to_account_metas;
15mod try_accounts;
16
17pub fn generate(accs: &AccountsStruct) -> proc_macro2::TokenStream {
18 let impl_try_accounts = try_accounts::generate(accs);
19 let impl_to_account_infos = to_account_infos::generate(accs);
20 let impl_to_account_metas = to_account_metas::generate(accs);
21 let impl_exit = exit::generate(accs);
22 let bumps_struct = bumps::generate(accs);
23
24 let __client_accounts_mod = __client_accounts::generate(accs, quote!(crate::ID));
25 let __cpi_client_accounts_mod = __cpi_client_accounts::generate(accs, quote!(crate::ID));
26
27 let ret = quote! {
28 #impl_try_accounts
29 #impl_to_account_infos
30 #impl_to_account_metas
31 #impl_exit
32 #bumps_struct
33
34 #__client_accounts_mod
35 #__cpi_client_accounts_mod
36 };
37
38 #[cfg(feature = "idl-build")]
39 {
40 let idl_build_impl = crate::idl::gen_idl_build_impl_accounts_struct(accs);
41 return quote! {
42 #ret
43 #idl_build_impl
44 };
45 }
46
47 #[allow(unreachable_code)]
48 ret
49}
50
51fn generics(accs: &AccountsStruct) -> ParsedGenerics {
52 let trait_lifetime = accs
53 .generics
54 .lifetimes()
55 .next()
56 .cloned()
57 .unwrap_or_else(|| syn::parse_str("'info").expect("Could not parse lifetime"));
58
59 let mut where_clause = accs.generics.where_clause.clone().unwrap_or(WhereClause {
60 where_token: Default::default(),
61 predicates: Default::default(),
62 });
63 for lifetime in accs.generics.lifetimes().map(|def| &def.lifetime) {
64 where_clause
65 .predicates
66 .push(WherePredicate::Lifetime(PredicateLifetime {
67 lifetime: lifetime.clone(),
68 colon_token: Default::default(),
69 bounds: iter::once(trait_lifetime.lifetime.clone()).collect(),
70 }))
71 }
72 let trait_lifetime = GenericParam::Lifetime(trait_lifetime);
73
74 ParsedGenerics {
75 combined_generics: if accs.generics.lifetimes().next().is_some() {
76 accs.generics.params.clone()
77 } else {
78 iter::once(trait_lifetime.clone())
79 .chain(accs.generics.params.clone())
80 .collect()
81 },
82 trait_generics: iter::once(trait_lifetime).collect(),
83 struct_generics: accs
84 .generics
85 .params
86 .clone()
87 .into_iter()
88 .map(|param: GenericParam| match param {
89 GenericParam::Const(ConstParam { ident, .. })
90 | GenericParam::Type(TypeParam { ident, .. }) => GenericParam::Type(TypeParam {
91 attrs: vec![],
92 ident,
93 colon_token: None,
94 bounds: Default::default(),
95 eq_token: None,
96 default: None,
97 }),
98 GenericParam::Lifetime(LifetimeDef { lifetime, .. }) => {
99 GenericParam::Lifetime(LifetimeDef {
100 attrs: vec![],
101 lifetime,
102 colon_token: None,
103 bounds: Default::default(),
104 })
105 }
106 })
107 .collect(),
108 where_clause,
109 }
110}
111
112struct ParsedGenerics {
113 pub combined_generics: Punctuated<GenericParam, Token![,]>,
114 pub trait_generics: Punctuated<GenericParam, Token![,]>,
115 pub struct_generics: Punctuated<GenericParam, Token![,]>,
116 pub where_clause: WhereClause,
117}