typhoon_accounts/accounts/
interface.rs

1use {
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}