vec.rs 2.9 KB

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