ospf_rust_base/
error.rs

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}