typhoon_context/args/
bytemuck.rs1use {
2 crate::HandlerContext,
3 bytemuck::AnyBitPattern,
4 solana_account_view::AccountView,
5 solana_address::Address,
6 typhoon_errors::{Error, ErrorCode},
7};
8
9#[derive(Debug)]
10pub struct Arg<'a, T>(pub &'a T);
11
12impl<'c, T> HandlerContext<'_, '_, 'c> for Arg<'c, T>
13where
14 T: AnyBitPattern,
15{
16 #[inline(always)]
17 fn from_entrypoint(
18 _program_id: &Address,
19 _accounts: &mut &[AccountView],
20 instruction_data: &mut &'c [u8],
21 ) -> Result<Self, Error> {
22 let len = core::mem::size_of::<T>();
23
24 if len > instruction_data.len() {
25 return Err(ErrorCode::InvalidDataLength.into());
26 }
27
28 let (arg_data, remaining) = unsafe { instruction_data.split_at_unchecked(len) };
33 let data_ptr = arg_data.as_ptr();
34
35 if data_ptr.align_offset(core::mem::align_of::<T>()) != 0 {
36 return Err(ErrorCode::InvalidDataAlignment.into());
37 }
38
39 let arg: &T = unsafe { &*(data_ptr as *const T) };
40
41 *instruction_data = remaining;
42
43 Ok(Arg(arg))
44 }
45}