sysvar.rs 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. use crate::{Accounts, AccountsExit, ToAccountInfo, ToAccountInfos, ToAccountMetas};
  2. use solana_program::account_info::AccountInfo;
  3. use solana_program::entrypoint::ProgramResult;
  4. use solana_program::instruction::AccountMeta;
  5. use solana_program::program_error::ProgramError;
  6. use solana_program::pubkey::Pubkey;
  7. use std::ops::{Deref, DerefMut};
  8. /// Container for sysvars.
  9. pub struct Sysvar<'info, T: solana_program::sysvar::Sysvar> {
  10. info: AccountInfo<'info>,
  11. account: T,
  12. }
  13. impl<'info, T: solana_program::sysvar::Sysvar> Sysvar<'info, T> {
  14. pub fn from_account_info(
  15. acc_info: &AccountInfo<'info>,
  16. ) -> Result<Sysvar<'info, T>, ProgramError> {
  17. Ok(Sysvar {
  18. info: acc_info.clone(),
  19. account: T::from_account_info(&acc_info)?,
  20. })
  21. }
  22. }
  23. impl<'info, T: solana_program::sysvar::Sysvar> Clone for Sysvar<'info, T> {
  24. fn clone(&self) -> Self {
  25. Self {
  26. info: self.info.clone(),
  27. account: T::from_account_info(&self.info).unwrap(),
  28. }
  29. }
  30. }
  31. impl<'info, T: solana_program::sysvar::Sysvar> Accounts<'info> for Sysvar<'info, T> {
  32. fn try_accounts(
  33. _program_id: &Pubkey,
  34. accounts: &mut &[AccountInfo<'info>],
  35. ) -> Result<Self, ProgramError> {
  36. if accounts.len() == 0 {
  37. return Err(ProgramError::NotEnoughAccountKeys);
  38. }
  39. let account = &accounts[0];
  40. *accounts = &accounts[1..];
  41. Sysvar::from_account_info(account)
  42. }
  43. }
  44. impl<'info, T: solana_program::sysvar::Sysvar> ToAccountMetas for Sysvar<'info, T> {
  45. fn to_account_metas(&self, _is_signer: Option<bool>) -> Vec<AccountMeta> {
  46. vec![AccountMeta::new_readonly(*self.info.key, false)]
  47. }
  48. }
  49. impl<'info, T: solana_program::sysvar::Sysvar> ToAccountInfos<'info> for Sysvar<'info, T> {
  50. fn to_account_infos(&self) -> Vec<AccountInfo<'info>> {
  51. vec![self.info.clone()]
  52. }
  53. }
  54. impl<'a, T: solana_program::sysvar::Sysvar> Deref for Sysvar<'a, T> {
  55. type Target = T;
  56. fn deref(&self) -> &Self::Target {
  57. &self.account
  58. }
  59. }
  60. impl<'a, T: solana_program::sysvar::Sysvar> DerefMut for Sysvar<'a, T> {
  61. fn deref_mut(&mut self) -> &mut Self::Target {
  62. &mut self.account
  63. }
  64. }
  65. impl<'info, T: solana_program::sysvar::Sysvar> ToAccountInfo<'info> for Sysvar<'info, T> {
  66. fn to_account_info(&self) -> AccountInfo<'info> {
  67. self.info.clone()
  68. }
  69. }
  70. impl<'info, T: solana_program::sysvar::Sysvar> AccountsExit<'info> for Sysvar<'info, T> {
  71. fn exit(&self, _program_id: &Pubkey) -> ProgramResult {
  72. // no-op
  73. Ok(())
  74. }
  75. }