use pinocchio::{account_info::AccountInfo, program_error::ProgramError};
pub trait DataLen {
const LEN: usize;
}
pub trait AccountUpdates {
type Update;
fn updates(&mut self, updates: Self::Update) -> Result<(), ProgramError>;
}
pub trait Validate<'info> {
fn validate(&self) -> Result<(), ProgramError>;
}
pub trait Context<'info>: Sized {
const ACCOUNTS_LEN: usize;
fn build(accounts: &'info [AccountInfo]) -> Result<Self, ProgramError>;
}
#[inline]
pub fn load<T: DataLen>(account: &AccountInfo) -> Result<&T, ProgramError> {
if account.data_len() != T::LEN {
return Err(ProgramError::InvalidAccountData);
}
Ok(unsafe {
&*core::mem::transmute::<*const u8, *const T>(account.borrow_data_unchecked().as_ptr())
})
}
#[inline]
pub fn load_mut<T: DataLen>(account: &AccountInfo) -> Result<&mut T, ProgramError> {
if account.data_len() != T::LEN {
return Err(ProgramError::InvalidAccountData);
}
Ok(unsafe {
&mut *core::mem::transmute::<*mut u8, *mut T>(
account.borrow_mut_data_unchecked().as_mut_ptr(),
)
})
}
#[inline]
pub fn load_discriminator(
account: &AccountInfo,
len: Option<usize>,
) -> Result<&[u8; 8], ProgramError> {
let discriminator_len = len.unwrap_or(8);
unsafe {
account.borrow_data_unchecked()[0..discriminator_len]
.try_into()
.map_err(|_| ProgramError::InvalidAccountData)
}
}