use std::fmt::{self, Debug, Display};
use derive_more::{Deref, DerefMut};
mod constants;
#[derive(Clone, Copy, Eq, PartialEq, Hash, Default, Deref, DerefMut)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[repr(transparent)]
pub struct Code(i32);
impl Display for Code {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_fmt(format_args!("{:#06X}", *self))
}
}
impl Debug for Code {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_fmt(format_args!("[{:#06X}] {}", self.0, self.as_err_str()))
}
}
impl Code {
pub fn success(&self) -> bool {
self.0 == 0
}
const fn as_err_str(&self) -> &'static str {
if self.0 == 0 {
return "Success";
}
match constants::error_str_of(self.0 as _) {
Some(s) => s,
None => "Incomplete",
}
}
pub(crate) const fn _priv_err_str(&self) -> Option<&'static str> {
constants::error_str_of(self.0 as _)
}
}
impl Code {
#[allow(non_upper_case_globals)]
#[deprecated(since = "0.9.0", note = "Use Code::FAILED instead")]
pub const Failed: Code = Code(0xFFFF);
#[allow(non_upper_case_globals)]
#[deprecated(since = "0.9.0", note = "Use Code::SUCCESS instead")]
pub const Success: Code = Code(0);
pub const FAILED: Code = Code(0xFFFF);
pub const SUCCESS: Code = Code(0);
pub const COLUMN_EXISTS: Code = Code(0x036B);
pub const COLUMN_NOT_EXIST: Code = Code(0x036C);
pub const TAG_ALREADY_EXIST: Code = Code(0x0369);
pub const TAG_NOT_EXIST: Code = Code(0x036A);
pub const MODIFIED_ALREADY: Code = Code(0x264B);
pub const INVALID_COLUMN_NAME: Code = Code(0x2602);
pub const TABLE_NOT_EXIST: Code = Code(0x2603);
pub const STABLE_NOT_EXIST: Code = Code(0x0362);
pub const INVALID_ROW_BYTES: Code = Code(0x036F);
pub const DUPLICATED_COLUMN_NAMES: Code = Code(0x263C);
pub const NO_COLUMN_CAN_BE_DROPPED: Code = Code(0x2651);
}
macro_rules! _impl_fmt {
($fmt:ident) => {
impl fmt::$fmt for Code {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::$fmt::fmt(&self.0, f)
}
}
};
}
_impl_fmt!(LowerHex);
_impl_fmt!(UpperHex);
macro_rules! _impl_from {
($($from:ty) *) => {
$(
impl From<$from> for Code {
#[inline]
fn from(c: $from) -> Self {
Self(c as i32 & 0xFFFF)
}
}
impl From<Code> for $from {
#[inline]
fn from(c: Code) -> Self {
c.0 as _
}
}
)*
};
}
_impl_from!(i8 u8 i16 i32 u16 u32 i64 u64);
impl Code {
pub const fn new(code: i32) -> Self {
Code(code)
}
}
impl PartialEq<usize> for Code {
fn eq(&self, other: &usize) -> bool {
self.0 == *other as i32
}
}
impl PartialEq<isize> for Code {
fn eq(&self, other: &isize) -> bool {
self.0 == *other as i32
}
}
impl PartialEq<i32> for Code {
fn eq(&self, other: &i32) -> bool {
self.0 == *other
}
}
#[test]
fn test_code() {
let c: i32 = Code::new(0).into();
assert_eq!(c, 0);
let c = Code::from(0).to_string();
assert_eq!(c, "0x0000");
dbg!(Code::from(0x200));
let c: i8 = Code::new(0).into();
let mut c: Code = c.into();
let _: &i32 = &c;
let _: &mut i32 = &mut c;
}