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