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