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