use core::fmt;
use borsh::{BorshDeserialize, BorshSerialize};
use serde::{Deserialize, Serialize};
#[derive(
Clone, Copy, Debug, Serialize, Deserialize, PartialEq, BorshSerialize, BorshDeserialize,
)]
#[non_exhaustive]
pub enum ExitCode {
Halted(u32),
Paused(u32),
SystemSplit,
SessionLimit,
}
impl ExitCode {
pub fn into_pair(self) -> (u32, u32) {
match self {
ExitCode::Halted(user_exit) => (0, user_exit),
ExitCode::Paused(user_exit) => (1, user_exit),
ExitCode::SystemSplit => (2, 0),
ExitCode::SessionLimit => (2, 2),
}
}
pub fn from_pair(sys_exit: u32, user_exit: u32) -> Result<ExitCode, InvalidExitCodeError> {
match sys_exit {
0 => Ok(ExitCode::Halted(user_exit)),
1 => Ok(ExitCode::Paused(user_exit)),
2 => Ok(ExitCode::SystemSplit),
_ => Err(InvalidExitCodeError(sys_exit, user_exit)),
}
}
pub fn expects_output(&self) -> bool {
match self {
ExitCode::Halted(_) | ExitCode::Paused(_) => true,
ExitCode::SystemSplit | ExitCode::SessionLimit => false,
}
}
pub fn is_ok(&self) -> bool {
matches!(self, ExitCode::Halted(0))
}
}
impl Eq for ExitCode {}
#[derive(Debug, Copy, Clone)]
pub struct InvalidExitCodeError(pub u32, pub u32);
impl fmt::Display for InvalidExitCodeError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "invalid exit code pair ({}, {})", self.0, self.1)
}
}
#[cfg(feature = "std")]
impl std::error::Error for InvalidExitCodeError {}