use hopper_runtime::error::ProgramError;
#[inline]
pub fn check_state_transition(
current: u8,
next: u8,
valid_transitions: &[(u8, u8)],
) -> Result<(), ProgramError> {
for &(from, to) in valid_transitions {
if from == current && to == next {
return Ok(());
}
}
Err(ProgramError::InvalidAccountData)
}
#[inline(always)]
pub fn check_state(data: &[u8], offset: usize, expected: u8) -> Result<(), ProgramError> {
if offset >= data.len() {
return Err(ProgramError::AccountDataTooSmall);
}
if data[offset] != expected {
return Err(ProgramError::InvalidAccountData);
}
Ok(())
}
#[inline(always)]
pub fn check_state_not(data: &[u8], offset: usize, rejected: u8) -> Result<(), ProgramError> {
if offset >= data.len() {
return Err(ProgramError::AccountDataTooSmall);
}
if data[offset] == rejected {
return Err(ProgramError::InvalidAccountData);
}
Ok(())
}
#[inline]
pub fn check_state_in(data: &[u8], offset: usize, allowed: &[u8]) -> Result<(), ProgramError> {
if offset >= data.len() {
return Err(ProgramError::AccountDataTooSmall);
}
let state = data[offset];
for &a in allowed {
if state == a {
return Ok(());
}
}
Err(ProgramError::InvalidAccountData)
}
#[inline]
pub fn transition_state(
data: &mut [u8],
offset: usize,
next: u8,
valid_transitions: &[(u8, u8)],
) -> Result<(), ProgramError> {
if offset >= data.len() {
return Err(ProgramError::AccountDataTooSmall);
}
let current = data[offset];
check_state_transition(current, next, valid_transitions)?;
data[offset] = next;
Ok(())
}