typhoon_context/
args.rs

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