use crate::{account_set::ClientAccountSet, prelude::*};
use ref_cast::{ref_cast_custom, RefCastCustom};
use std::marker::PhantomData;
#[derive(AccountSet, Debug, RefCastCustom, derive_where::DeriveWhere)]
#[derive_where(Clone, Copy)]
#[account_set(skip_client_account_set)]
#[validate(
extra_validation = self.check_id(),
)]
#[repr(transparent)]
pub struct Program<T: StarFrameProgram>(
#[single_account_set]
#[idl(address = T::ID)]
pub(crate) AccountInfo,
#[account_set(skip = PhantomData)] pub(crate) PhantomData<T>,
);
impl<T: StarFrameProgram> ClientAccountSet for Program<T> {
type ClientAccounts = Option<Pubkey>;
const MIN_LEN: usize = 1;
fn extend_account_metas(
_program_id: &Pubkey,
accounts: &Self::ClientAccounts,
metas: &mut Vec<AccountMeta>,
) {
metas.push(AccountMeta::new_readonly(accounts.unwrap_or(T::ID), false));
}
}
impl<T: StarFrameProgram> Program<T> {
pub fn check_id(&self) -> Result<()> {
if self.0.pubkey().fast_eq(&T::ID) {
Ok(())
} else {
Err(ProgramError::IncorrectProgramId.into())
}
}
#[allow(dead_code)]
#[ref_cast_custom]
pub(crate) fn cast_info_unchecked<'a>(info: &'a AccountInfo) -> &'a Self;
}