pub use cruiser_derive::InstructionList;
use crate::account_argument::AccountInfoIterator;
use crate::account_list::AccountList;
use crate::compressed_numbers::CompressedNumber;
use crate::{CruiserResult, SolanaInstruction};
use solana_program::pubkey::Pubkey;
pub trait InstructionList: Copy {
type DiscriminantCompressed: CompressedNumber<Num = u64>;
type AccountList: AccountList;
fn discriminant(self) -> u64;
fn discriminant_compressed(self) -> Self::DiscriminantCompressed {
Self::DiscriminantCompressed::from_number(self.discriminant())
}
fn from_discriminant(discriminant: u64) -> Option<Self>;
}
pub trait InstructionListProcessor<AI, IL: InstructionList> {
fn process_instruction(
program_id: &Pubkey,
accounts: &mut impl AccountInfoIterator<Item = AI>,
data: &[u8],
) -> CruiserResult<()>;
}
pub trait InstructionListCPI<IL: InstructionList> {
type AccountInfo;
#[must_use]
fn instruction(&mut self, program_id: &Pubkey) -> SolanaInstruction;
}
pub trait InstructionListCPIStatic<IL: InstructionList, const N: usize>:
InstructionListCPI<IL>
{
#[must_use]
fn to_accounts_static<'a>(
&'a self,
program_account: &'a Self::AccountInfo,
) -> [&'a Self::AccountInfo; N];
}
pub trait InstructionListCPIDynamic<IL: InstructionList>:
for<'a> InstructionListCPIDynamicAccess<'a, IL>
{
}
impl<IL: InstructionList, T> InstructionListCPIDynamic<IL> for T where
T: for<'a> InstructionListCPIDynamicAccess<'a, IL>
{
}
pub trait InstructionListCPIDynamicAccess<'a, IL: InstructionList>: InstructionListCPI<IL>
where
Self::AccountInfo: 'a,
{
type Iter: Iterator<Item = &'a Self::AccountInfo>;
#[must_use]
fn to_accounts_dynamic(&'a self) -> Self::Iter;
}
#[cfg(feature = "interface")]
pub trait Interface: InstructionList {
const DEVELOPER_DISCRIMINANT: &'static [u8];
const INTERFACE_DISCRIMINANT: u64;
}
#[cfg(feature = "interface")]
pub trait InterfaceProcessor<AI, I: Interface>: InstructionListProcessor<AI, I> {}