1pub type FECode = u32;
7
8pub type FRes<T> = Result<T, FErr>;
10
11pub trait FECheckOk {
13 fn check_ok(self) -> bool;
15}
16
17impl<T> FECheckOk for Result<T, FErr> {
18 #[inline]
19 fn check_ok(self) -> bool {
20 const SEPERATOR: &'static str = "\n----------\n";
21 match self {
22 Err(e) => {
23 eprintln!("{SEPERATOR}FErr {{ code: {}, msg: {} }}{SEPERATOR}", e.code, e.msg);
24 false
25 }
26 Ok(_) => true,
27 }
28 }
29}
30
31#[derive(Debug, Clone, Eq, PartialEq)]
33pub struct FErr {
34 pub code: FECode,
36
37 pub msg: std::borrow::Cow<'static, str>,
39}
40
41impl FErr {
42 #[inline]
44 pub fn new(code: FECode, msg: &'static str) -> Self {
45 Self {
46 code,
47 msg: std::borrow::Cow::Borrowed(msg),
48 }
49 }
50
51 #[inline]
53 pub fn with_msg(code: FECode, msg: String) -> Self {
54 Self {
55 code,
56 msg: std::borrow::Cow::Owned(msg),
57 }
58 }
59
60 #[inline]
62 pub fn with_err<E>(code: FECode, err: E) -> Self
63 where
64 E: std::fmt::Display,
65 {
66 Self {
67 code,
68 msg: std::borrow::Cow::Owned(err.to_string()),
69 }
70 }
71}
72
73pub const fn new_err_code(module: u8, domain: u8, reason: u16) -> FECode {
80 debug_assert!(module <= 0x10, "Module should be 0-16");
82 debug_assert!(domain >= 0x11 && domain <= 0x20, "Domain should be 17-32");
83
84 ((module as u32) << 24) | ((domain as u32) << 16) | (reason as u32)
85}
86
87#[cfg(test)]
88mod fe {
89 use super::*;
90
91 const fn from_err_code(code: FECode) -> (u8, u8, u16) {
92 let reason = code as u16;
93 let domain = (code >> 16) as u8;
94 let module = (code >> 24) as u8;
95
96 (module, domain, reason)
97 }
98
99 #[test]
100 fn err_code_roundtrip() {
101 let module: u8 = 0x0A;
102 let domain: u8 = 0x15;
103 let reason: u16 = 0xBEEF;
104
105 let code = new_err_code(module, domain, reason);
106 let (m, d, r) = from_err_code(code);
107
108 assert_eq!(m, module);
109 assert_eq!(d, domain);
110 assert_eq!(r, reason);
111 assert_eq!(code, 0x0A15BEEF);
112 }
113}