1use crate::*;
2use core::fmt;
3
4#[cfg_attr(
5 feature = "xdrs",
6 derive(
7 xdrs::ReadXDR,
8 xdrs::WriteXDR,
9 xdrs::ConstWriteXDR,
10 xdrs::ConstXDRSize
11 )
12)]
13#[derive(Copy, Clone, PartialEq, Eq)]
14#[cfg_attr(feature = "std", derive(thiserror::Error))]
15#[cfg_attr(feature = "std", error("{:?}", self))]
16#[repr(transparent)]
17pub struct SysErr(pub i32);
24
25impl SysErr {
26 pub fn is_code(&self, code: SyscallErrorCode) -> bool {
28 self.0 == code.0
29 }
30
31 pub fn is_none(&self) -> bool {
33 self.is_code(SyscallErrorCode::kSyscallErrorCodeNone)
34 }
35
36 pub fn is_some(&self) -> bool {
38 !self.is_none()
39 }
40
41 pub fn is_storage_key_not_exist(self) -> bool {
44 self.is_code(SyscallErrorCode::kSyscallErrorCodeStorageKeyNotExist)
45 }
46
47 pub fn is_invalid_input(self) -> bool {
50 self.is_code(SyscallErrorCode::kSyscallErrorCodeInvalidSyscallInput)
51 }
52}
53
54impl fmt::Debug for SysErr {
55 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
56 let code = SyscallErrorCode(self.0);
57 match code {
58 SyscallErrorCode::kSyscallErrorCodeNone => {
59 write!(f, "SysErr<None>")
60 }
61 SyscallErrorCode::kSyscallErrorCodeFault => {
62 write!(f, "SysErr<Fault>")
63 }
64 SyscallErrorCode::kSyscallErrorCodeNoSyscall => {
65 write!(f, "SysErr<NoSyscall>")
66 }
67 SyscallErrorCode::kSyscallErrorCodeIsRootTransaction => {
68 write!(f, "SysErr<IsRootTransaction>")
69 }
70 SyscallErrorCode::kSyscallErrorCodeReentrance => {
71 write!(f, "SysErr<Reentrance>")
72 }
73 SyscallErrorCode::kSyscallErrorCodeContractAlreadyDeployed => {
74 write!(f, "SysErr<ContractAlreadyDeployed>")
75 }
76 SyscallErrorCode::kSyscallErrorCodeNoReturnBufferAvailable => {
77 write!(f, "SysErr<NoReturnBufferAvailable>")
78 }
79 SyscallErrorCode::kSyscallErrorCodeInvalidSyscallInput => {
80 write!(f, "SysErr<InvalidSyscallInput>")
81 }
82 SyscallErrorCode::kSyscallErrorCodeStorageKeyNotExist => {
83 write!(f, "SysErr<StorageKeyNotExist>")
84 }
85 SyscallErrorCode::kSyscallErrorCodeNoRetrocausalQueueEntry => {
86 write!(f, "SysErr<NoRetrocausalQueueEntry>")
87 }
88 SyscallErrorCode::kSyscallErrorCodeRetrocausalQueueReadLimitReached => {
89 write!(f, "SysErr<RetrocausalQueueReadLimitReached>")
90 }
91 SyscallErrorCode::kSyscallErrorCodeInvokeDepthExceeded => {
92 write!(f, "SysErr<InvokeDepthExceeded>")
93 }
94 _ => write!(f, "SysErr({})", self.0),
95 }
96 }
97}
98
99impl From<SyscallErrorCode> for SysErr {
100 fn from(code: SyscallErrorCode) -> Self {
101 SysErr(code.0)
102 }
103}
104
105impl From<SysErr> for i32 {
106 fn from(err: SysErr) -> Self {
107 err.0
108 }
109}
110
111#[cfg(test)]
112mod tests {
113 use super::*;
114 use std::format;
115
116 #[test]
117 fn debug_names_every_known_code() {
118 for code in
119 0..=SyscallErrorCode::kSyscallErrorCodeInvokeDepthExceeded.0
120 {
121 let debug = format!("{:?}", SysErr(code));
122 assert!(debug.starts_with("SysErr<"), "{code} prints as {debug}");
123 }
124 assert_eq!(format!("{:?}", SysErr(1000)), "SysErr(1000)");
125 }
126}