anchor_idl_mod/
state.rs

1use std::collections::BTreeMap;
2
3use anchor_syn::idl::{IdlField, IdlTypeDefinition};
4use proc_macro2::TokenStream;
5use quote::{format_ident, quote};
6
7use crate::{generate_fields, get_field_list_properties, StructOpts};
8
9/// Generates an account state struct.
10pub fn generate_account(
11    defs: &[IdlTypeDefinition],
12    account_name: &str,
13    fields: &[IdlField],
14    opts: StructOpts,
15) -> TokenStream {
16    let props = get_field_list_properties(defs, fields);
17
18    let derive_copy = if props.can_copy && !opts.zero_copy {
19        quote! {
20            #[derive(Copy)]
21        }
22    } else {
23        quote! {}
24    };
25    let derive_default = if props.can_derive_default {
26        quote! {
27            #[derive(Default)]
28        }
29    } else {
30        quote! {}
31    };
32    let derive_account = if opts.zero_copy {
33        let repr = if opts.packed {
34            quote! {
35                #[repr(packed)]
36            }
37        } else {
38            quote! {
39                #[repr(C)]
40            }
41        };
42        quote! {
43            #[account(zero_copy)]
44            #repr
45        }
46    } else {
47        quote! {
48            #[account]
49        }
50    };
51
52    let doc = format!(" Account: {}", account_name);
53    let struct_name = format_ident!("{}", account_name);
54    let fields_rendered = generate_fields(fields);
55    quote! {
56        #derive_account
57        #[doc = #doc]
58        #derive_copy
59        #derive_default
60        pub struct #struct_name {
61            #fields_rendered
62        }
63    }
64}
65
66/// Generates account state structs.
67pub fn generate_accounts(
68    typedefs: &[IdlTypeDefinition],
69    account_defs: &[IdlTypeDefinition],
70    struct_opts: &BTreeMap<String, StructOpts>,
71) -> TokenStream {
72    let defined = account_defs.iter().map(|def| match &def.ty {
73        anchor_syn::idl::IdlTypeDefinitionTy::Struct { fields } => {
74            let opts = struct_opts.get(&def.name).copied().unwrap_or_default();
75            generate_account(typedefs, &def.name, fields, opts)
76        }
77        anchor_syn::idl::IdlTypeDefinitionTy::Enum { .. } => {
78            panic!("unexpected enum account");
79        }
80    });
81    quote! {
82        #(#defined)*
83    }
84}