1use fvm_shared2::error::ExitCode as ExitCodeV2;
4use fvm_shared3::error::ExitCode as ExitCodeV3;
5use fvm_shared4::error::ExitCode as ExitCodeV4;
6use fvm_shared4::error::ExitCode as ExitCode_latest;
7use schemars::JsonSchema;
8use serde::{Deserialize, Serialize};
9use std::cmp::Ordering;
10use std::fmt;
11
12#[derive(
28 PartialEq,
29 Eq,
30 Debug,
31 Clone,
32 Copy,
33 Serialize,
34 Deserialize,
35 JsonSchema,
36 derive_more::From,
37 derive_more::Into,
38)]
39pub struct ExitCode(#[schemars(with = "u32")] ExitCodeV4);
40
41impl PartialOrd for ExitCode {
42 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
43 Some(self.value().cmp(&other.value()))
44 }
45}
46
47impl fmt::Display for ExitCode {
48 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
49 let name = match self.0 {
50 ExitCode_latest::SYS_SENDER_INVALID => Some("SysErrSenderInvalid"),
51 ExitCode_latest::SYS_SENDER_STATE_INVALID => Some("SysErrSenderStateInvalid"),
52 ExitCode_latest::SYS_ILLEGAL_INSTRUCTION => Some("SysErrIllegalInstruction"),
53 ExitCode_latest::SYS_INVALID_RECEIVER => Some("SysErrInvalidReceiver"),
54 ExitCode_latest::SYS_INSUFFICIENT_FUNDS => Some("SysErrInsufficientFunds"),
55 ExitCode_latest::SYS_OUT_OF_GAS => Some("SysErrOutOfGas"),
56 ExitCode_latest::SYS_ILLEGAL_EXIT_CODE => Some("SysErrIllegalExitCode"),
57 ExitCode_latest::SYS_ASSERTION_FAILED => Some("SysFatal"),
58 ExitCode_latest::SYS_MISSING_RETURN => Some("SysErrMissingReturn"),
59
60 ExitCode_latest::USR_ILLEGAL_ARGUMENT => Some("ErrIllegalArgument"),
61 ExitCode_latest::USR_NOT_FOUND => Some("ErrNotFound"),
62 ExitCode_latest::USR_FORBIDDEN => Some("ErrForbidden"),
63 ExitCode_latest::USR_INSUFFICIENT_FUNDS => Some("ErrInsufficientFunds"),
64 ExitCode_latest::USR_ILLEGAL_STATE => Some("ErrIllegalState"),
65 ExitCode_latest::USR_SERIALIZATION => Some("ErrSerialization"),
66 ExitCode_latest::USR_UNHANDLED_MESSAGE => Some("ErrUnhandledMessage"),
67 ExitCode_latest::USR_UNSPECIFIED => Some("ErrUnspecified"),
68 ExitCode_latest::USR_ASSERTION_FAILED => Some("ErrAssertionFailed"),
69 ExitCode_latest::USR_READ_ONLY => Some("ErrReadOnly"),
70 ExitCode_latest::USR_NOT_PAYABLE => Some("ErrNotPayable"),
71
72 _ => None,
73 };
74 if let Some(name) = name {
75 write!(f, "{}({})", name, self.value())
76 } else {
77 match self.value() {
78 code if code > ExitCode_latest::SYS_MISSING_RETURN.value()
79 && code < ExitCode_latest::FIRST_USER_EXIT_CODE =>
80 {
81 write!(
84 f,
85 "SysErrReserved{}({})",
86 code - (ExitCode_latest::SYS_ASSERTION_FAILED.value()),
87 code
88 )
89 }
90 _ => write!(f, "{}", self.value()),
91 }
92 }
93 }
94}
95
96impl ExitCode {
97 pub const FIRST_USER_EXIT_CODE: u32 = ExitCode_latest::FIRST_USER_EXIT_CODE;
99
100 pub const SYS_OUT_OF_GAS: Self = Self::new(ExitCode_latest::SYS_OUT_OF_GAS);
102
103 pub const SYS_INSUFFICIENT_FUNDS: Self = Self::new(ExitCode_latest::SYS_INSUFFICIENT_FUNDS);
105
106 pub const FIRST_ACTOR_ERROR_CODE: u32 = 16;
109
110 pub fn value(&self) -> u32 {
111 self.0.value()
112 }
113
114 pub fn is_success(&self) -> bool {
115 self.0.is_success()
116 }
117
118 pub const fn new(value: ExitCode_latest) -> Self {
119 Self(value)
120 }
121}
122
123impl From<u32> for ExitCode {
124 fn from(value: u32) -> Self {
125 Self(ExitCodeV4::new(value))
126 }
127}
128
129impl From<ExitCodeV3> for ExitCode {
130 fn from(value: ExitCodeV3) -> Self {
131 value.value().into()
132 }
133}
134
135impl From<ExitCodeV2> for ExitCode {
136 fn from(value: ExitCodeV2) -> Self {
137 value.value().into()
138 }
139}
140
141impl From<ExitCode> for ExitCodeV2 {
142 fn from(value: ExitCode) -> Self {
143 Self::new(value.0.value())
144 }
145}
146
147impl From<ExitCode> for ExitCodeV3 {
148 fn from(value: ExitCode) -> Self {
149 Self::new(value.0.value())
150 }
151}