use fvm_shared2::error::ExitCode as ExitCodeV2;
use fvm_shared3::error::ExitCode as ExitCodeV3;
use fvm_shared4::error::ExitCode as ExitCodeV4;
use fvm_shared4::error::ExitCode as ExitCode_latest;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use std::cmp::Ordering;
use std::fmt;
#[derive(
PartialEq,
Eq,
Debug,
Clone,
Copy,
Serialize,
Deserialize,
JsonSchema,
derive_more::From,
derive_more::Into,
)]
pub struct ExitCode(#[schemars(with = "u32")] ExitCodeV4);
impl PartialOrd for ExitCode {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.value().cmp(&other.value()))
}
}
impl fmt::Display for ExitCode {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let name = match self.0 {
ExitCode_latest::SYS_SENDER_INVALID => Some("SysErrSenderInvalid"),
ExitCode_latest::SYS_SENDER_STATE_INVALID => Some("SysErrSenderStateInvalid"),
ExitCode_latest::SYS_ILLEGAL_INSTRUCTION => Some("SysErrIllegalInstruction"),
ExitCode_latest::SYS_INVALID_RECEIVER => Some("SysErrInvalidReceiver"),
ExitCode_latest::SYS_INSUFFICIENT_FUNDS => Some("SysErrInsufficientFunds"),
ExitCode_latest::SYS_OUT_OF_GAS => Some("SysErrOutOfGas"),
ExitCode_latest::SYS_ILLEGAL_EXIT_CODE => Some("SysErrIllegalExitCode"),
ExitCode_latest::SYS_ASSERTION_FAILED => Some("SysFatal"),
ExitCode_latest::SYS_MISSING_RETURN => Some("SysErrMissingReturn"),
ExitCode_latest::USR_ILLEGAL_ARGUMENT => Some("ErrIllegalArgument"),
ExitCode_latest::USR_NOT_FOUND => Some("ErrNotFound"),
ExitCode_latest::USR_FORBIDDEN => Some("ErrForbidden"),
ExitCode_latest::USR_INSUFFICIENT_FUNDS => Some("ErrInsufficientFunds"),
ExitCode_latest::USR_ILLEGAL_STATE => Some("ErrIllegalState"),
ExitCode_latest::USR_SERIALIZATION => Some("ErrSerialization"),
ExitCode_latest::USR_UNHANDLED_MESSAGE => Some("ErrUnhandledMessage"),
ExitCode_latest::USR_UNSPECIFIED => Some("ErrUnspecified"),
ExitCode_latest::USR_ASSERTION_FAILED => Some("ErrAssertionFailed"),
ExitCode_latest::USR_READ_ONLY => Some("ErrReadOnly"),
ExitCode_latest::USR_NOT_PAYABLE => Some("ErrNotPayable"),
_ => None,
};
if let Some(name) = name {
write!(f, "{}({})", name, self.value())
} else {
match self.value() {
code if code > ExitCode_latest::SYS_MISSING_RETURN.value()
&& code < ExitCode_latest::FIRST_USER_EXIT_CODE =>
{
write!(
f,
"SysErrReserved{}({})",
code - (ExitCode_latest::SYS_ASSERTION_FAILED.value()),
code
)
}
_ => write!(f, "{}", self.value()),
}
}
}
}
impl ExitCode {
pub const FIRST_USER_EXIT_CODE: u32 = ExitCode_latest::FIRST_USER_EXIT_CODE;
pub const SYS_OUT_OF_GAS: Self = Self::new(ExitCode_latest::SYS_OUT_OF_GAS);
pub const SYS_INSUFFICIENT_FUNDS: Self = Self::new(ExitCode_latest::SYS_INSUFFICIENT_FUNDS);
pub const FIRST_ACTOR_ERROR_CODE: u32 = 16;
pub fn value(&self) -> u32 {
self.0.value()
}
pub fn is_success(&self) -> bool {
self.0.is_success()
}
pub const fn new(value: ExitCode_latest) -> Self {
Self(value)
}
}
impl From<u32> for ExitCode {
fn from(value: u32) -> Self {
Self(ExitCodeV4::new(value))
}
}
impl From<ExitCodeV3> for ExitCode {
fn from(value: ExitCodeV3) -> Self {
value.value().into()
}
}
impl From<ExitCodeV2> for ExitCode {
fn from(value: ExitCodeV2) -> Self {
value.value().into()
}
}
impl From<ExitCode> for ExitCodeV2 {
fn from(value: ExitCode) -> Self {
Self::new(value.0.value())
}
}
impl From<ExitCode> for ExitCodeV3 {
fn from(value: ExitCode) -> Self {
Self::new(value.0.value())
}
}