Skip to main content

anchor_lang/
vec.rs

1// Avoiding AccountInfo deprecated msg in anchor context
2#![allow(deprecated)]
3use {
4    crate::{
5        solana_program::{account_info::AccountInfo, instruction::AccountMeta, pubkey::Pubkey},
6        Accounts, Result, ToAccountInfos, ToAccountMetas,
7    },
8    std::collections::BTreeSet,
9};
10
11impl<'info, T: ToAccountInfos<'info>> ToAccountInfos<'info> for Vec<T> {
12    fn to_account_infos(&self) -> Vec<AccountInfo<'info>> {
13        self.iter()
14            .flat_map(|item| item.to_account_infos())
15            .collect()
16    }
17}
18
19impl<T: ToAccountMetas> ToAccountMetas for Vec<T> {
20    fn to_account_metas(&self, is_signer: Option<bool>) -> Vec<AccountMeta> {
21        self.iter()
22            .flat_map(|item| (*item).to_account_metas(is_signer))
23            .collect()
24    }
25}
26
27impl<'info, B, T: Accounts<'info, B>> Accounts<'info, B> for Vec<T> {
28    fn try_accounts(
29        program_id: &Pubkey,
30        accounts: &mut &'info [AccountInfo<'info>],
31        ix_data: &[u8],
32        bumps: &mut B,
33        reallocs: &mut BTreeSet<Pubkey>,
34    ) -> Result<Self> {
35        let mut vec: Vec<T> = Vec::new();
36        T::try_accounts(program_id, accounts, ix_data, bumps, reallocs)
37            .map(|item| vec.push(item))?;
38        Ok(vec)
39    }
40}
41
42#[cfg(test)]
43mod tests {
44    use {super::*, crate::solana_program::pubkey::Pubkey};
45
46    #[derive(Accounts)]
47    pub struct Test<'info> {
48        #[account(signer)]
49        test: AccountInfo<'info>,
50    }
51
52    #[test]
53    fn test_accounts_trait_for_vec() {
54        let program_id = Pubkey::default();
55
56        let key = Pubkey::default();
57        let mut lamports1 = 0;
58        let mut data1 = vec![0; 10];
59        let owner = Pubkey::default();
60        let account1 =
61            AccountInfo::new(&key, true, true, &mut lamports1, &mut data1, &owner, false);
62
63        let mut lamports2 = 0;
64        let mut data2 = vec![0; 10];
65        let account2 =
66            AccountInfo::new(&key, true, true, &mut lamports2, &mut data2, &owner, false);
67        let mut bumps = TestBumps::default();
68        let mut reallocs = std::collections::BTreeSet::new();
69        let mut accounts = &[account1, account2][..];
70        let parsed_accounts =
71            Vec::<Test>::try_accounts(&program_id, &mut accounts, &[], &mut bumps, &mut reallocs)
72                .unwrap();
73
74        assert_eq!(accounts.len(), parsed_accounts.len());
75    }
76
77    #[test]
78    #[should_panic]
79    fn test_accounts_trait_for_vec_empty() {
80        let program_id = Pubkey::default();
81        let mut bumps = TestBumps::default();
82        let mut reallocs = std::collections::BTreeSet::new();
83        let mut accounts = &[][..];
84        Vec::<Test>::try_accounts(&program_id, &mut accounts, &[], &mut bumps, &mut reallocs)
85            .unwrap();
86    }
87}