1use paste::paste;
2use strum::{ EnumString, Display };
3
4#[repr(u8)]
5#[derive(EnumString, Clone, Copy, Display, Debug, PartialEq, Eq, PartialOrd, Ord)]
6pub enum ErrorCode {
7 #[strum(serialize = "none")]
8 None = 0u8,
9
10 #[strum(serialize = "not a file")]
11 NotAFile = 0x10u8,
12 #[strum(serialize = "not a directory")]
13 NotADirectory = 0x11u8,
14 #[strum(serialize = "file not found")]
15 FileNotFound = 0x12u8,
16 #[strum(serialize = "directory unusable")]
17 DirectoryUnusable = 0x13u8,
18 #[strum(serialize = "file extension not matched")]
19 FileExtensionNotMatched = 0x14u8,
20 #[strum(serialize = "data not found")]
21 DataNotFound = 0x15u8,
22 #[strum(serialize = "data empty")]
23 DataEmpty = 0x16u8,
24 #[strum(disabled)]
25 EnumVisitorEmpty = 0x17u8,
26 #[strum(disabled)]
27 UniqueBoxLocked = 0x18u8,
28 #[strum(disabled)]
29 UniqueRefLocked = 0x19u8,
30 #[strum(serialize = "serialization failed")]
31 SerializationFailed = 0x1au8,
32 #[strum(serialize = "deserialization failed")]
33 DeserializationFailed = 0x1bu8,
34
35 #[strum(serialize = "token existed")]
36 TokenExisted = 0x20u8,
37 #[strum(serialize = "symbol repetitive")]
38 SymbolRepetitive = 0x21u8,
39 #[strum(serialize = "lack of pipelines")]
40 LackOfPipelines = 0x22u8,
41 #[strum(serialize = "solver not found")]
42 SolverNotFound = 0x23u8,
43 #[strum(serialize = "OR engine environment lost")]
44 OREngineEnvironmentLost = 0x24u8,
45 #[strum(serialize = "OR engine connection overtime")]
46 OREngineConnectionOvertime = 0x25u8,
47 #[strum(serialize = "OR engine modeling exception")]
48 OREngineModelingException = 0x26u8,
49 #[strum(serialize = "OR engine solving exception")]
50 OREngineSolvingException = 0x27u8,
51 #[strum(serialize = "OR engine terminated")]
52 OREngineTerminated = 0x28u8,
53 #[strum(serialize = "OR model no solution")]
54 ORModelNoSolution = 0x29u8,
55 #[strum(serialize = "OR model unbounded")]
56 ORModelUnbounded = 0x2au8,
57 #[strum(serialize = "OR solution invalid")]
58 ORSolutionInvalid = 0x2bu8,
59
60 #[strum(serialize = "application failed")]
61 ApplicationFailed = 0x30u8,
62 #[strum(serialize = "application error")]
63 ApplicationError = 0x31u8,
64 #[strum(serialize = "application exception")]
65 ApplicationException = 0x32u8,
66 #[strum(serialize = "application stopped")]
67 ApplicationStopped = 0x33u8,
68 #[strum(serialize = "illegal argument")]
69 IllegalArgument = 0x34u8,
70
71 #[strum(serialize = "other")]
72 Other = u8::MAX - 1,
73 #[strum(serialize = "unknown")]
74 Unknown = u8::MAX,
75}
76
77impl From<u8> for ErrorCode {
78 fn from(value: u8) -> Self {
79 unsafe { std::mem::transmute(value) }
80 }
81}
82
83impl Into<u8> for ErrorCode {
84 fn into(self) -> u8 {
85 self as u8
86 }
87}
88
89pub trait Error {
90 fn msg(&self) -> &str;
91}
92
93pub trait ExError<T: Sized>: Error {
94 fn arg(&self) -> &Option<T>;
95}
96
97pub trait LogicError: Error {}
98
99pub trait RuntimeError: Error {
100 fn code(&self) -> ErrorCode;
101}
102
103pub trait ExLogicError<T: Sized>: LogicError + ExError<T> {}
104
105pub trait ExRuntimeError<T: Sized>: RuntimeError + ExError<T> {}
106
107macro_rules! logic_error_template {
108 ($($type:ident)*) => ($(
109 pub struct $type {
110 msg: String
111 }
112
113 impl Error for $type {
114 fn msg(&self) -> &str { &self.msg }
115 }
116
117 impl LogicError for $type {}
118
119 paste! {
120 pub struct [<Ex $type>]<T: Sized> {
121 msg: String,
122 arg: Option<T>
123 }
124
125 impl<T: Sized> Error for [<Ex $type>]<T> {
126 fn msg(&self) -> &str { &self.msg }
127 }
128
129 impl<T: Sized> ExError<T> for [<Ex $type>]<T> {
130 fn arg(&self) -> &Option<T> { &self.arg }
131 }
132
133 impl<T: Sized> LogicError for [<Ex $type>]<T> {}
134 impl<T: Sized> ExLogicError<T> for [<Ex $type>]<T> {}
135 }
136 )*)
137}
138logic_error_template! { InvalidArgument DomainError LengthError OutOfRange }
139
140macro_rules! runtime_error_template {
141 ($($type:ident)*) => ($(
142 pub struct $type {
143 code: ErrorCode,
144 msg: String
145 }
146
147 impl Error for $type {
148 fn msg(&self) -> &str { &self.msg }
149 }
150
151 impl RuntimeError for $type {
152 fn code(&self) -> ErrorCode { self.code }
153 }
154
155 paste! {
156 pub struct [<Ex $type>]<T: Sized> {
157 code: ErrorCode,
158 msg: String,
159 arg: Option<T>
160 }
161
162 impl<T: Sized> Error for [<Ex $type>]<T> {
163 fn msg(&self) -> &str { &self.msg }
164 }
165
166 impl<T: Sized> ExError<T> for [<Ex $type>]<T> {
167 fn arg(&self) -> &Option<T> { &self.arg }
168 }
169
170 impl<T: Sized> RuntimeError for [<Ex $type>]<T> {
171 fn code(&self) -> ErrorCode { self.code }
172 }
173
174 impl<T: Sized> ExRuntimeError<T> for [<Ex $type>]<T> {}
175 }
176 )*)
177}
178runtime_error_template! { ApplicationError RangeError OverflowError UnderflowError SystemError FilesystemError }
179
180pub struct Ok {}
181pub const OK: Ok = Ok {};
182
183impl<E> From<Ok> for Result<(), E> {
184 fn from(_: Ok) -> Self { Ok(()) }
185}