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}