anchor_lang/
vec.rs

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