1#![no_std]
2
3pub use {accounts::*, discriminator::*, programs::*};
4use {
5 bytemuck::{AnyBitPattern, NoUninit},
6 solana_account_view::AccountView,
7 solana_address::Address,
8 typhoon_errors::Error,
9 typhoon_traits::Discriminator,
10};
11
12mod accounts;
13mod discriminator;
14mod programs;
15
16pub trait FromAccountInfo<'a>: Sized {
17 fn try_from_info(info: &'a AccountView) -> Result<Self, Error>;
18}
19
20pub trait ReadableAccount: AsRef<AccountView> {
21 type DataUnchecked: ?Sized;
22 type Data<'a>
23 where
24 Self: 'a;
25
26 #[inline(always)]
27 fn address(&self) -> &Address {
28 self.as_ref().address()
29 }
30
31 #[inline(always)]
32 fn owned_by(&self, owner: &Address) -> bool {
33 self.as_ref().owned_by(owner)
34 }
35
36 #[inline(always)]
37 fn lamports(&self) -> u64 {
38 self.as_ref().lamports()
39 }
40
41 fn data<'a>(&'a self) -> Result<Self::Data<'a>, Error>;
42
43 fn data_unchecked(&self) -> Result<&Self::DataUnchecked, Error>;
44}
45
46pub trait WritableAccount: ReadableAccount {
47 type DataMut<'a>
48 where
49 Self: 'a;
50
51 #[inline(always)]
52 fn assign(&self, new_owner: &Address) {
53 unsafe {
54 self.as_ref().assign(new_owner);
55 }
56 }
57
58 #[inline(always)]
59 fn resize(&self, new_len: usize) -> Result<(), Error> {
60 self.as_ref().resize(new_len).map_err(Into::into)
61 }
62
63 #[inline(always)]
64 fn set_lamports(&self, lamports: u64) {
65 self.as_ref().set_lamports(lamports);
66 }
67
68 fn mut_data<'a>(&'a self) -> Result<Self::DataMut<'a>, Error>;
69}
70
71pub trait SignerAccount: ReadableAccount {}
72
73pub trait RefFromBytes {
74 fn read(data: &[u8]) -> Option<&Self>;
75 fn read_mut(data: &mut [u8]) -> Option<&mut Self>;
76}
77
78impl<T> RefFromBytes for T
79where
80 T: Discriminator + AnyBitPattern + NoUninit,
81{
82 fn read(data: &[u8]) -> Option<&Self> {
83 let dis_len = T::DISCRIMINATOR.len();
84 let total_len = dis_len + core::mem::size_of::<T>();
85
86 if data.len() < total_len {
87 return None;
88 }
89
90 let data_ptr = data[dis_len..total_len].as_ptr();
91
92 if data_ptr.align_offset(core::mem::align_of::<T>()) != 0 {
93 return None;
94 }
95
96 Some(unsafe { &*(data_ptr as *const T) })
97 }
98
99 fn read_mut(data: &mut [u8]) -> Option<&mut Self> {
100 let dis_len = T::DISCRIMINATOR.len();
101 let total_len = dis_len + core::mem::size_of::<T>();
102
103 if data.len() < total_len {
104 return None;
105 }
106
107 let data_ptr = data[dis_len..total_len].as_mut_ptr();
108
109 if data_ptr.align_offset(core::mem::align_of::<T>()) != 0 {
110 return None;
111 }
112
113 Some(unsafe { &mut *(data_ptr as *mut T) })
114 }
115}
116
117pub trait FromRaw<'a> {
118 fn from_raw(info: &'a AccountView) -> Self;
119}