typhoon_accounts/accounts/
interface.rs1use {
2 crate::{FromAccountInfo, ProgramIds, ReadableAccount},
3 core::marker::PhantomData,
4 pinocchio::{
5 account_info::{AccountInfo, Ref},
6 program_error::ProgramError,
7 },
8 typhoon_errors::Error,
9};
10
11pub struct Interface<'a, T> {
12 info: &'a AccountInfo,
13 _phantom: PhantomData<T>,
14}
15
16impl<'a, T> FromAccountInfo<'a> for Interface<'a, T>
17where
18 T: ProgramIds,
19{
20 #[inline(always)]
21 fn try_from_info(info: &'a AccountInfo) -> Result<Self, Error> {
22 if !T::IDS.contains(info.key()) {
23 return Err(ProgramError::IncorrectProgramId.into());
24 }
25
26 if !info.executable() {
27 return Err(ProgramError::InvalidAccountOwner.into());
28 }
29
30 Ok(Interface {
31 info,
32 _phantom: PhantomData,
33 })
34 }
35}
36
37impl<'a, T> From<Interface<'a, T>> for &'a AccountInfo {
38 #[inline(always)]
39 fn from(value: Interface<'a, T>) -> Self {
40 value.info
41 }
42}
43
44impl<T> AsRef<AccountInfo> for Interface<'_, T> {
45 #[inline(always)]
46 fn as_ref(&self) -> &AccountInfo {
47 self.info
48 }
49}
50
51impl<T> ReadableAccount for Interface<'_, T> {
52 type DataUnchecked = [u8];
53 type Data<'a>
54 = Ref<'a, [u8]>
55 where
56 Self: 'a;
57
58 #[inline(always)]
59 fn data<'a>(&'a self) -> Result<Self::Data<'a>, Error> {
60 self.info.try_borrow_data().map_err(Into::into)
61 }
62
63 #[inline]
64 fn data_unchecked(&self) -> Result<&Self::DataUnchecked, Error> {
65 Ok(unsafe { self.info.borrow_data_unchecked() })
66 }
67}