1use std::fmt::{self, Debug, Display};
2
3use derive_more::{Deref, DerefMut};
4
5mod constants;
6
7#[derive(Clone, Copy, Eq, PartialEq, Hash, Default, Deref, DerefMut)]
9#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
10#[repr(transparent)]
11pub struct Code(i32);
12
13impl Display for Code {
14 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
15 f.write_fmt(format_args!("{:#06X}", *self))
16 }
17}
18
19impl Debug for Code {
20 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
21 f.write_fmt(format_args!("[{:#06X}] {}", self.0, self.as_err_str()))
22 }
23}
24
25impl Code {
26 pub fn success(&self) -> bool {
28 self.0 == 0
29 }
30
31 const fn as_err_str(&self) -> &'static str {
32 if self.0 == 0 {
33 return "Success";
34 }
35 match constants::error_str_of(self.0 as _) {
36 Some(s) => s,
37 None => "Incomplete",
38 }
39 }
40 pub(crate) const fn _priv_err_str(&self) -> Option<&'static str> {
41 constants::error_str_of(self.0 as _)
42 }
43}
44
45impl Code {
47 #[allow(non_upper_case_globals)]
48 #[deprecated(since = "0.9.0", note = "Use Code::FAILED instead")]
49 pub const Failed: Code = Code(0xFFFF);
50 #[allow(non_upper_case_globals)]
51 #[deprecated(since = "0.9.0", note = "Use Code::SUCCESS instead")]
52 pub const Success: Code = Code(0);
53
54 pub const FAILED: Code = Code(0xFFFF);
55 pub const SUCCESS: Code = Code(0);
56
57 pub const COLUMN_EXISTS: Code = Code(0x036B);
58 pub const COLUMN_NOT_EXIST: Code = Code(0x036C);
59 pub const TAG_ALREADY_EXIST: Code = Code(0x0369);
60 pub const TAG_NOT_EXIST: Code = Code(0x036A);
61 pub const MODIFIED_ALREADY: Code = Code(0x264B);
62 pub const INVALID_COLUMN_NAME: Code = Code(0x2602);
63 pub const TABLE_NOT_EXIST: Code = Code(0x2603);
64 pub const STABLE_NOT_EXIST: Code = Code(0x0362);
65 pub const INVALID_ROW_BYTES: Code = Code(0x036F);
66 pub const DUPLICATED_COLUMN_NAMES: Code = Code(0x263C);
67 pub const NO_COLUMN_CAN_BE_DROPPED: Code = Code(0x2651);
68}
69
70macro_rules! _impl_fmt {
71 ($fmt:ident) => {
72 impl fmt::$fmt for Code {
73 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
74 fmt::$fmt::fmt(&self.0, f)
75 }
76 }
77 };
78}
79
80_impl_fmt!(LowerHex);
81_impl_fmt!(UpperHex);
82
83macro_rules! _impl_from {
84 ($($from:ty) *) => {
85 $(
86 impl From<$from> for Code {
87 #[inline]
88 fn from(c: $from) -> Self {
89 Self(c as i32 & 0xFFFF)
90 }
91 }
92 impl From<Code> for $from {
93 #[inline]
94 fn from(c: Code) -> Self {
95 c.0 as _
96 }
97 }
98 )*
99 };
100}
101
102_impl_from!(i8 u8 i16 i32 u16 u32 i64 u64);
103
104impl Code {
105 pub const fn new(code: i32) -> Self {
107 Code(code)
108 }
109}
110
111impl PartialEq<usize> for Code {
112 fn eq(&self, other: &usize) -> bool {
113 self.0 == *other as i32
114 }
115}
116
117impl PartialEq<isize> for Code {
118 fn eq(&self, other: &isize) -> bool {
119 self.0 == *other as i32
120 }
121}
122
123impl PartialEq<i32> for Code {
124 fn eq(&self, other: &i32) -> bool {
125 self.0 == *other
126 }
127}
128
129#[test]
130fn test_code() {
131 let c: i32 = Code::new(0).into();
132 assert_eq!(c, 0);
133 let c = Code::from(0).to_string();
134 assert_eq!(c, "0x0000");
135 dbg!(Code::from(0x200));
136
137 let c: i8 = Code::new(0).into();
138 let mut c: Code = c.into();
139
140 let _: &i32 = &c;
141 let _: &mut i32 = &mut c;
142}