anchor_lang/accounts/
option.rs1use {
12 crate::{
13 error::ErrorCode,
14 solana_program::{account_info::AccountInfo, instruction::AccountMeta, pubkey::Pubkey},
15 Accounts, AccountsClose, AccountsExit, Result, ToAccountInfos, ToAccountMetas,
16 },
17 std::collections::BTreeSet,
18};
19
20impl<'info, B, T: Accounts<'info, B>> Accounts<'info, B> for Option<T> {
21 fn try_accounts(
22 program_id: &Pubkey,
23 accounts: &mut &'info [AccountInfo<'info>],
24 ix_data: &[u8],
25 bumps: &mut B,
26 reallocs: &mut BTreeSet<Pubkey>,
27 ) -> Result<Self> {
28 if accounts.is_empty() {
29 return if cfg!(feature = "allow-missing-optionals") {
30 Ok(None)
36 } else {
37 Err(ErrorCode::AccountNotEnoughKeys.into())
40 };
41 }
42
43 if accounts[0].key == program_id {
46 *accounts = &accounts[1..];
47 Ok(None)
48 } else {
49 T::try_accounts(program_id, accounts, ix_data, bumps, reallocs).map(Some)
53 }
54 }
55}
56
57impl<'info, T: ToAccountInfos<'info>> ToAccountInfos<'info> for Option<T> {
58 fn to_account_infos(&self) -> Vec<AccountInfo<'info>> {
59 self.as_ref()
60 .map_or_else(Vec::new, |account| account.to_account_infos())
61 }
62}
63
64impl<T: ToAccountMetas> ToAccountMetas for Option<T> {
65 fn to_account_metas(&self, is_signer: Option<bool>) -> Vec<AccountMeta> {
66 self.as_ref()
67 .expect("Cannot run `to_account_metas` on None")
68 .to_account_metas(is_signer)
69 }
70}
71
72impl<'info, T: AccountsClose<'info>> AccountsClose<'info> for Option<T> {
73 fn close(&self, sol_destination: AccountInfo<'info>) -> Result<()> {
74 self.as_ref()
75 .map_or(Ok(()), |t| T::close(t, sol_destination))
76 }
77}
78
79impl<'info, T: AccountsExit<'info>> AccountsExit<'info> for Option<T> {
80 fn exit(&self, program_id: &Pubkey) -> Result<()> {
81 self.as_ref().map_or(Ok(()), |t| t.exit(program_id))
82 }
83}