vec.rs 2.7 KB

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