use {
crate::{FromAccountInfo, ReadableAccount},
core::marker::PhantomData,
pinocchio::hint::unlikely,
solana_account_view::AccountView,
solana_program_error::ProgramError,
typhoon_errors::Error,
typhoon_traits::CheckProgramId,
};
pub struct Program<'a, T> {
info: &'a AccountView,
_phantom: PhantomData<T>,
}
impl<'a, T> FromAccountInfo<'a> for Program<'a, T>
where
T: CheckProgramId,
{
#[inline]
fn try_from_info(info: &'a AccountView) -> Result<Self, Error> {
if unlikely(!T::address_eq(info.address())) {
return Err(ProgramError::IncorrectProgramId.into());
}
if !info.executable() {
return Err(ProgramError::InvalidAccountOwner.into());
}
Ok(Program {
info,
_phantom: PhantomData,
})
}
}
impl<'a, T> From<Program<'a, T>> for &'a AccountView {
#[inline(always)]
fn from(value: Program<'a, T>) -> Self {
value.info
}
}
impl<T> AsRef<AccountView> for Program<'_, T> {
#[inline(always)]
fn as_ref(&self) -> &AccountView {
self.info
}
}
impl<T> ReadableAccount for Program<'_, T> {}