typhoon_context/args/
borsh.rs1use {
2 crate::HandlerContext, borsh::BorshDeserialize, solana_account_view::AccountView,
3 solana_address::Address, solana_program_error::ProgramError, typhoon_errors::Error,
4};
5
6pub struct BorshArg<T>(pub T);
7
8impl<T> HandlerContext<'_, '_, '_> for BorshArg<T>
9where
10 T: BorshDeserialize,
11{
12 #[inline(always)]
13 fn from_entrypoint(
14 _program_id: &Address,
15 _accounts: &mut &[AccountView],
16 instruction_data: &mut &[u8],
17 ) -> Result<Self, Error> {
18 let arg = T::deserialize(instruction_data).map_err(|_| ProgramError::BorshIoError)?;
19
20 Ok(BorshArg(arg))
21 }
22}
23
24#[cfg(test)]
25mod tests {
26 use {super::*, borsh::BorshSerialize};
27
28 #[test]
29 fn test_borsh_arg_deserialization() {
30 let mut instruction_data = [0_u8; 8];
31 42_u64
32 .serialize(&mut instruction_data.as_mut_slice())
33 .unwrap();
34 assert_eq!(instruction_data, [42, 0, 0, 0, 0, 0, 0, 0]);
35 let mut accounts: &[AccountView] = &[];
36
37 let mut instruction_data_slice = instruction_data.as_slice();
38 let result: BorshArg<u64> = BorshArg::from_entrypoint(
39 &Address::default(),
40 &mut accounts,
41 &mut instruction_data_slice,
42 )
43 .unwrap_or(BorshArg(0));
44 assert_eq!(result.0, 42);
45 assert_eq!(instruction_data_slice.len(), 0);
46 }
47}