typhoon_context/args/
bytemuck.rs

1use {
2    crate::HandlerContext,
3    bytemuck::{try_from_bytes, AnyBitPattern},
4    core::ops::Deref,
5    pinocchio::{account_info::AccountInfo, program_error::ProgramError, pubkey::Pubkey},
6    typhoon_errors::Error,
7};
8
9#[derive(Debug)]
10pub struct Arg<'a, T>(&'a T);
11
12impl<'a, T> Arg<'a, T> {
13    #[inline(always)]
14    pub fn new(arg: &'a T) -> Self {
15        Arg(arg)
16    }
17}
18
19impl<T> Deref for Arg<'_, T> {
20    type Target = T;
21
22    #[inline(always)]
23    fn deref(&self) -> &Self::Target {
24        self.0
25    }
26}
27
28impl<'c, T> HandlerContext<'_, '_, 'c> for Arg<'c, T>
29where
30    T: AnyBitPattern,
31{
32    #[inline(always)]
33    fn from_entrypoint(
34        _program_id: &Pubkey,
35        _accounts: &mut &[AccountInfo],
36        instruction_data: &mut &'c [u8],
37    ) -> Result<Self, Error> {
38        let (arg_data, remaining) = instruction_data.split_at(core::mem::size_of::<T>());
39
40        let arg: &T = try_from_bytes(arg_data).map_err(|_| ProgramError::InvalidInstructionData)?;
41
42        *instruction_data = remaining;
43
44        Ok(Arg::new(arg))
45    }
46}