typhoon_context/args/
bytemuck.rs1use {
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<'a, T> HandlerContext<'a> for Arg<'a, T>
29where
30 T: AnyBitPattern,
31{
32 #[inline(always)]
33 fn from_entrypoint(
34 _program_id: &Pubkey,
35 _accounts: &mut &'a [AccountInfo],
36 instruction_data: &mut &'a [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}