spherenet_program_whitelist_interface/state/
mod.rs

1pub mod account;
2pub mod whitelist_entry;
3
4use {bytemuck::Pod, core::mem, pinocchio::program_error::ProgramError, shank::ShankType};
5
6/// Trait for types that have a fixed, known size
7pub trait SizeOf {
8    /// Size of the type in bytes
9    const SIZE_OF: usize;
10}
11
12/// Implement SizeOf for all Pod types
13impl<T: Pod> SizeOf for T {
14    const SIZE_OF: usize = mem::size_of::<T>();
15}
16
17/// Trait to represent a type that can be initialized.
18pub trait Initializable {
19    /// Return `true` if the object is initialized.
20    fn is_initialized(&self) -> bool;
21}
22
23/// Representation of account state initialized flag.
24#[repr(u8)]
25#[derive(Clone, Copy, Debug, PartialEq, ShankType)]
26pub enum AccountState {
27    /// Account is not yet initialized
28    Uninitialized,
29    /// Account has been initialized
30    Initialized,
31}
32
33/// Load a reference for an initialized `T` from the given bytes
34#[inline(always)]
35pub fn load<'data, T: Pod + Initializable>(input: &'data [u8]) -> Result<&'data T, ProgramError> {
36    if input.len() != T::SIZE_OF {
37        return Err(ProgramError::InvalidAccountData);
38    }
39
40    let account = bytemuck::from_bytes::<T>(input);
41
42    if !account.is_initialized() {
43        return Err(ProgramError::UninitializedAccount);
44    }
45
46    Ok(account)
47}
48
49/// Load a mutable reference for an initialized `T` from the given bytes
50#[inline(always)]
51pub fn load_mut<'data, T: Pod + Initializable>(
52    input: &'data mut [u8],
53) -> Result<&'data mut T, ProgramError> {
54    if input.len() != T::SIZE_OF {
55        return Err(ProgramError::InvalidAccountData);
56    }
57
58    let account = bytemuck::from_bytes_mut::<T>(input);
59
60    if !account.is_initialized() {
61        return Err(ProgramError::UninitializedAccount);
62    }
63
64    Ok(account)
65}
66
67/// Load a reference without checking if the data is initialized
68#[inline(always)]
69pub fn load_unchecked<'data, T: Pod>(input: &'data [u8]) -> Result<&'data T, ProgramError> {
70    if input.len() != T::SIZE_OF {
71        return Err(ProgramError::InvalidAccountData);
72    }
73
74    Ok(bytemuck::from_bytes::<T>(input))
75}
76
77/// Load a mutable reference without checking if the data is initialized
78#[inline(always)]
79pub fn load_mut_unchecked<'data, T: Pod>(
80    input: &'data mut [u8],
81) -> Result<&'data mut T, ProgramError> {
82    if input.len() != T::SIZE_OF {
83        return Err(ProgramError::InvalidAccountData);
84    }
85
86    Ok(bytemuck::from_bytes_mut::<T>(input))
87}