1use core::marker::PhantomData;
9
10use crate::{AccountView, Address, LayoutContract, ProgramError};
11
12#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
13pub struct Unchecked;
14#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
15pub struct OwnerChecked;
16#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
17pub struct LayoutChecked<T>(PhantomData<T>);
18#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
19pub struct SignerChecked;
20#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
21pub struct WritableChecked;
22#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
23pub struct ExecutableChecked;
24#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
25pub struct TokenExtensionsChecked;
26#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
27pub struct SeedsChecked;
28#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
29pub struct HasOneChecked;
30
31#[derive(Clone, Copy)]
32pub struct AccountProof<'a, P = Unchecked> {
33 account: &'a AccountView,
34 _proof: PhantomData<P>,
35}
36
37impl<'a> AccountProof<'a, Unchecked> {
38 #[inline(always)]
39 pub const fn new(account: &'a AccountView) -> Self {
40 Self {
41 account,
42 _proof: PhantomData,
43 }
44 }
45}
46
47impl<'a, P> AccountProof<'a, P> {
48 #[inline(always)]
49 pub const fn account(&self) -> &'a AccountView {
50 self.account
51 }
52
53 #[inline(always)]
54 pub fn check_owner(
55 self,
56 expected: &Address,
57 ) -> Result<AccountProof<'a, (P, OwnerChecked)>, ProgramError> {
58 self.account.check_owned_by(expected)?;
59 Ok(AccountProof::<'a, (P, OwnerChecked)> {
60 account: self.account,
61 _proof: PhantomData,
62 })
63 }
64
65 #[inline(always)]
66 pub fn check_layout<T: LayoutContract>(
67 self,
68 ) -> Result<AccountProof<'a, (P, LayoutChecked<T>)>, ProgramError> {
69 self.account.check_layout::<T>()?;
70 Ok(AccountProof::<'a, (P, LayoutChecked<T>)> {
71 account: self.account,
72 _proof: PhantomData,
73 })
74 }
75
76 #[inline(always)]
77 pub fn check_signer(self) -> Result<AccountProof<'a, (P, SignerChecked)>, ProgramError> {
78 self.account.check_signer()?;
79 Ok(AccountProof::<'a, (P, SignerChecked)> {
80 account: self.account,
81 _proof: PhantomData,
82 })
83 }
84
85 #[inline(always)]
86 pub fn check_writable(self) -> Result<AccountProof<'a, (P, WritableChecked)>, ProgramError> {
87 self.account.check_writable()?;
88 Ok(AccountProof::<'a, (P, WritableChecked)> {
89 account: self.account,
90 _proof: PhantomData,
91 })
92 }
93
94 #[inline(always)]
95 pub fn check_executable(
96 self,
97 ) -> Result<AccountProof<'a, (P, ExecutableChecked)>, ProgramError> {
98 self.account.check_executable()?;
99 Ok(AccountProof::<'a, (P, ExecutableChecked)> {
100 account: self.account,
101 _proof: PhantomData,
102 })
103 }
104
105 #[inline(always)]
106 pub const fn assume_token_extensions_checked(
107 self,
108 ) -> AccountProof<'a, (P, TokenExtensionsChecked)> {
109 AccountProof::<'a, (P, TokenExtensionsChecked)> {
110 account: self.account,
111 _proof: PhantomData,
112 }
113 }
114}