use core::fmt::Display;
#[derive(Copy, Clone)]
pub struct Flag {
pub flag: u8,
}
#[derive(Clone, Copy, PartialEq)]
pub enum Rela {
LEFT,
RIGHT,
ROOT,
}
pub const LEFT: u8 = 0b00;
pub const RIGHT: u8 = 0b01;
pub const ROOT: u8 = 0b10;
impl From<u8> for Rela {
fn from(flag: u8) -> Self {
match flag {
LEFT => Rela::LEFT,
RIGHT => Rela::RIGHT,
ROOT => Rela::ROOT,
_ => unreachable!(),
}
}
}
impl Into<u8> for Rela {
fn into(self) -> u8 {
self as u8
}
}
impl Into<usize> for Rela {
fn into(self) -> usize {
self as usize
}
}
impl Display for Rela {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
Rela::LEFT => write!(f, "L"),
Rela::RIGHT => write!(f, "R"),
Rela::ROOT => write!(f, "T"),
}
}
}
#[derive(Clone, Copy, PartialEq)]
pub enum Color {
RED,
BLACK,
}
pub const RED: u8 = 0b0000;
pub const BLACK: u8 = 0b100;
impl Color {
pub fn as_u8(&self) -> u8 {
match self {
Color::RED => RED,
Color::BLACK => BLACK,
}
}
}
impl From<u8> for Color {
fn from(flag: u8) -> Self {
match flag {
RED => Color::RED,
BLACK => Color::BLACK,
_ => unreachable!(),
}
}
}
impl Into<u8> for Color {
fn into(self) -> u8 {
(self as u8) << 2
}
}
impl Display for Color {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
Color::RED => write!(f, "R"),
Color::BLACK => write!(f, "B"),
}
}
}
impl Flag {
#[inline(always)]
pub fn is_red(&self) -> bool {
self.flag & 0b0100 == RED
}
#[inline(always)]
pub fn is_black(&self) -> bool {
self.flag & 0b0100 == BLACK
}
#[inline(always)]
pub fn is_root(&self) -> bool {
self.flag & 0b10 == ROOT
}
#[inline(always)]
pub fn is_left(&self) -> bool {
self.flag & 0b11 == LEFT
}
#[inline(always)]
pub fn is_right(&self) -> bool {
self.flag & 0b11 == RIGHT
}
#[inline(always)]
pub fn set_rela(&mut self, rela: u8) -> &mut Self {
self.flag = (self.flag & 0b11111100) | rela;
self
}
#[inline(always)]
pub fn set_color(&mut self, color: Color) -> &mut Self {
self.flag = (self.flag & 0b11111011) | color.as_u8();
self
}
#[inline(always)]
pub fn set_red(&mut self) -> &mut Self {
self.flag = (self.flag & 0b11111011) | RED;
self
}
#[inline(always)]
pub fn set_black(&mut self) -> &mut Self {
self.flag = (self.flag & 0b11111011) | BLACK;
self
}
#[inline(always)]
pub fn set_root(&mut self) -> &mut Self {
self.flag = (self.flag & 0b11111000) | ROOT | BLACK;
self
}
#[inline(always)]
pub fn clear_root(&mut self) -> &mut Self {
self.flag = self.flag & &!ROOT;
self
}
#[inline(always)]
pub fn rela(&self) -> u8 {
self.flag & 0b11
}
#[inline(always)]
pub fn color(&self) -> Color {
Color::from(self.flag & 0b0100)
}
}
pub fn toggle_rela(rela: u8) -> u8 {
match rela {
0 => 1,
1 => 0,
2 => 2,
_ => unreachable!(),
}
}