use hopper_runtime::error::ProgramError;
#[inline(always)]
pub fn dispatch_instruction(data: &[u8]) -> Result<(u8, &[u8]), ProgramError> {
if data.is_empty() {
return Err(ProgramError::InvalidInstructionData);
}
Ok((data[0], &data[1..]))
}
#[inline(always)]
pub fn dispatch_instruction_u16(data: &[u8]) -> Result<(u16, &[u8]), ProgramError> {
if data.len() < 2 {
return Err(ProgramError::InvalidInstructionData);
}
let tag = u16::from_le_bytes([data[0], data[1]]);
Ok((tag, &data[2..]))
}
#[inline(always)]
pub fn dispatch_instruction_8(data: &[u8]) -> Result<([u8; 8], &[u8]), ProgramError> {
if data.len() < 8 {
return Err(ProgramError::InvalidInstructionData);
}
let mut disc = [0u8; 8];
disc.copy_from_slice(&data[..8]);
Ok((disc, &data[8..]))
}
pub const EVENT_CPI_PREFIX: [u8; 2] = [0xFF, 0xFE];
#[macro_export]
macro_rules! hopper_dispatch {
(
$program_id:expr, $accounts:expr, $data:expr;
$( $tag:literal => $handler:expr ),+ $(,)?
) => {{
if $data.len() >= 2 && $data[0] == 0xFF && $data[1] == 0xFE {
return Ok(());
}
let (tag, remaining) = $crate::dispatch::dispatch_instruction($data)?;
match tag {
$( $tag => $handler($program_id, $accounts, remaining), )+
_ => Err($crate::__runtime::error::ProgramError::InvalidInstructionData),
}
}};
}
#[macro_export]
macro_rules! hopper_dispatch_lazy {
(
$ctx:expr;
$( $tag:literal => $handler:expr ),+ $(,)?
) => {{
let data = $ctx.instruction_data();
if data.len() >= 2 && data[0] == 0xFF && data[1] == 0xFE {
return Ok(());
}
if data.is_empty() {
return Err($crate::__runtime::error::ProgramError::InvalidInstructionData);
}
let tag = data[0];
match tag {
$( $tag => $handler($ctx), )+
_ => Err($crate::__runtime::error::ProgramError::InvalidInstructionData),
}
}};
}
#[macro_export]
macro_rules! hopper_dispatch_8 {
(
$program_id:expr, $accounts:expr, $data:expr;
$( [ $($disc:literal),+ ] => $handler:expr ),+ $(,)?
) => {{
if $data.len() >= 2 && $data[0] == 0xFF && $data[1] == 0xFE {
return Ok(());
}
let (disc, remaining) = $crate::dispatch::dispatch_instruction_8($data)?;
match disc {
$( [ $($disc),+ ] => $handler($program_id, $accounts, remaining), )+
_ => Err($crate::__runtime::error::ProgramError::InvalidInstructionData),
}
}};
}