pub mod account;
use {bytemuck::Pod, core::mem, pinocchio::program_error::ProgramError, shank::ShankType};
pub trait SizeOf {
const SIZE_OF: usize;
}
impl<T: Pod> SizeOf for T {
const SIZE_OF: usize = mem::size_of::<T>();
}
pub trait Initializable {
fn is_initialized(&self) -> bool;
}
#[repr(u8)]
#[derive(Clone, Copy, Debug, PartialEq, ShankType)]
pub enum AccountState {
Uninitialized,
Initialized,
}
#[inline(always)]
pub fn load<T: Pod + Initializable>(input: &[u8]) -> Result<&T, ProgramError> {
if input.len() != T::SIZE_OF {
return Err(ProgramError::InvalidAccountData);
}
let account = bytemuck::from_bytes::<T>(input);
if !account.is_initialized() {
return Err(ProgramError::UninitializedAccount);
}
Ok(account)
}
#[inline(always)]
pub fn load_mut<T: Pod + Initializable>(
input: &mut [u8],
) -> Result<&mut T, ProgramError> {
if input.len() != T::SIZE_OF {
return Err(ProgramError::InvalidAccountData);
}
let account = bytemuck::from_bytes_mut::<T>(input);
if !account.is_initialized() {
return Err(ProgramError::UninitializedAccount);
}
Ok(account)
}
#[inline(always)]
pub fn load_unchecked<T: Pod>(input: &[u8]) -> Result<&T, ProgramError> {
if input.len() != T::SIZE_OF {
return Err(ProgramError::InvalidAccountData);
}
Ok(bytemuck::from_bytes::<T>(input))
}
#[inline(always)]
pub fn load_mut_unchecked<T: Pod>(
input: &mut [u8],
) -> Result<&mut T, ProgramError> {
if input.len() != T::SIZE_OF {
return Err(ProgramError::InvalidAccountData);
}
Ok(bytemuck::from_bytes_mut::<T>(input))
}