use super::BitmapSize;
use core::fmt::Formatter;
use serde::{Deserialize, Serialize};
use std::{
fmt::{Debug, Display},
mem,
ops::{
Add, AddAssign, BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Deref, Div,
DivAssign, Mul, MulAssign, Not, Shl, ShlAssign, Shr, ShrAssign, Sub, SubAssign,
},
};
#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Hash, Default, Serialize, Deserialize)]
pub struct Bitmap8(u8);
impl Bitmap8 {
pub fn capacity() -> usize {
Bitmap8::MAP_LENGTH
}
pub fn to_u8(&self) -> u8 {
self.0
}
pub fn new(value: bool) -> Bitmap8 {
Bitmap8(if value { u8::MAX } else { 0 })
}
pub fn create_bit_mask(begin: usize, end: usize, value: bool) -> Bitmap8 {
if value {
if begin >= Bitmap8::MAP_LENGTH || end < 1 {
Bitmap8(0)
} else if end >= Bitmap8::MAP_LENGTH {
Bitmap8(u8::MAX << begin)
} else {
Bitmap8(u8::MAX << begin & u8::MAX >> Bitmap8::MAP_LENGTH - end)
}
} else {
!Bitmap8::create_bit_mask(begin, end, true)
}
}
pub fn from_set(index: usize) -> Option<Bitmap8> {
if index >= Bitmap8::MAP_LENGTH {
return None;
}
let mut bitmap = Bitmap8::default();
bitmap.set(index, true).unwrap();
Some(bitmap)
}
pub fn set(&mut self, index: usize, value: bool) -> Result<(), String> {
if index >= Bitmap8::MAP_LENGTH {
return Err(String::from(
"Tried to set bit that's out of range of the bitmap (range: ",
) + &Bitmap8::MAP_LENGTH.to_string()
+ ", index: "
+ &index.to_string()
+ ")");
}
if value {
let mask = 1 << index;
self.0 |= mask;
} else {
let mask = u8::MAX - (1 << index);
self.0 &= mask;
}
Ok(())
}
pub fn set_range(&mut self, begin: usize, end: usize, value: bool) {
if value {
*self |= Bitmap8::create_bit_mask(begin, end, true);
} else {
*self &= Bitmap8::create_bit_mask(begin, end, false);
}
}
pub fn get(&self, index: usize) -> Result<bool, String> {
if index >= Bitmap8::MAP_LENGTH {
return Err(String::from(
"Tried to get bit that's out of range of the bitmap (range: ",
) + &Bitmap8::MAP_LENGTH.to_string()
+ ", index: "
+ &index.to_string()
+ ")");
}
let mask = 1 << index;
Ok(self.0 & mask > 0)
}
}
impl Display for Bitmap8 {
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
write!(f, "{:b}", self.0)
}
}
impl Debug for Bitmap8 {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "Bitmap8({:X})", self.0)
}
}
impl From<u8> for Bitmap8 {
fn from(value: u8) -> Self {
Bitmap8(value)
}
}
impl BitmapSize for Bitmap8 {
const MAP_LENGTH: usize = mem::size_of::<u8>() * 8;
}
impl BitAnd for Bitmap8 {
type Output = Self;
fn bitand(self, rhs: Self) -> Self::Output {
Self(self.0 & rhs.0)
}
}
impl BitAndAssign for Bitmap8 {
fn bitand_assign(&mut self, rhs: Self) {
self.0 &= rhs.0;
}
}
impl BitOr for Bitmap8 {
type Output = Self;
fn bitor(self, rhs: Self) -> Self::Output {
Self(self.0 | rhs.0)
}
}
impl BitOrAssign for Bitmap8 {
fn bitor_assign(&mut self, rhs: Self) {
self.0 |= rhs.0;
}
}
impl BitXor for Bitmap8 {
type Output = Self;
fn bitxor(self, rhs: Self) -> Self::Output {
Self(self.0 ^ rhs.0)
}
}
impl BitXorAssign for Bitmap8 {
fn bitxor_assign(&mut self, rhs: Self) {
self.0 ^= rhs.0;
}
}
impl Add for Bitmap8 {
type Output = Self;
fn add(self, rhs: Self) -> Self::Output {
Self(self.0 + rhs.0)
}
}
impl AddAssign for Bitmap8 {
fn add_assign(&mut self, rhs: Self) {
self.0 += rhs.0;
}
}
impl Sub for Bitmap8 {
type Output = Self;
fn sub(self, rhs: Self) -> Self::Output {
Self(self.0 - rhs.0)
}
}
impl SubAssign for Bitmap8 {
fn sub_assign(&mut self, rhs: Self) {
self.0 -= rhs.0;
}
}
impl Mul for Bitmap8 {
type Output = Self;
fn mul(self, rhs: Self) -> Self::Output {
Self(self.0 * rhs.0)
}
}
impl MulAssign for Bitmap8 {
fn mul_assign(&mut self, rhs: Self) {
self.0 *= rhs.0;
}
}
impl Div for Bitmap8 {
type Output = Self;
fn div(self, rhs: Self) -> Self::Output {
Self(self.0 / rhs.0)
}
}
impl DivAssign for Bitmap8 {
fn div_assign(&mut self, rhs: Self) {
self.0 /= rhs.0;
}
}
impl BitAnd<u8> for Bitmap8 {
type Output = Self;
fn bitand(self, rhs: u8) -> Self::Output {
Self(self.0 & rhs)
}
}
impl BitAndAssign<u8> for Bitmap8 {
fn bitand_assign(&mut self, rhs: u8) {
self.0 &= rhs;
}
}
impl BitOr<u8> for Bitmap8 {
type Output = Self;
fn bitor(self, rhs: u8) -> Self::Output {
Self(self.0 | rhs)
}
}
impl BitOrAssign<u8> for Bitmap8 {
fn bitor_assign(&mut self, rhs: u8) {
self.0 |= rhs;
}
}
impl BitXor<u8> for Bitmap8 {
type Output = Self;
fn bitxor(self, rhs: u8) -> Self::Output {
Self(self.0 ^ rhs)
}
}
impl BitXorAssign<u8> for Bitmap8 {
fn bitxor_assign(&mut self, rhs: u8) {
self.0 ^= rhs;
}
}
impl Add<u8> for Bitmap8 {
type Output = Self;
fn add(self, rhs: u8) -> Self::Output {
Self(self.0 + rhs)
}
}
impl AddAssign<u8> for Bitmap8 {
fn add_assign(&mut self, rhs: u8) {
self.0 += rhs;
}
}
impl Sub<u8> for Bitmap8 {
type Output = Self;
fn sub(self, rhs: u8) -> Self::Output {
Self(self.0 - rhs)
}
}
impl SubAssign<u8> for Bitmap8 {
fn sub_assign(&mut self, rhs: u8) {
self.0 -= rhs;
}
}
impl Mul<u8> for Bitmap8 {
type Output = Self;
fn mul(self, rhs: u8) -> Self::Output {
Self(self.0 * rhs)
}
}
impl MulAssign<u8> for Bitmap8 {
fn mul_assign(&mut self, rhs: u8) {
self.0 *= rhs;
}
}
impl Div<u8> for Bitmap8 {
type Output = Self;
fn div(self, rhs: u8) -> Self::Output {
Self(self.0 / rhs)
}
}
impl DivAssign<u8> for Bitmap8 {
fn div_assign(&mut self, rhs: u8) {
self.0 /= rhs;
}
}
impl Shl<usize> for Bitmap8 {
type Output = Self;
fn shl(self, rhs: usize) -> Self::Output {
Self(self.0 << rhs)
}
}
impl ShlAssign<usize> for Bitmap8 {
fn shl_assign(&mut self, rhs: usize) {
self.0 <<= rhs;
}
}
impl Shr<usize> for Bitmap8 {
type Output = Self;
fn shr(self, rhs: usize) -> Self::Output {
Self(self.0 >> rhs)
}
}
impl ShrAssign<usize> for Bitmap8 {
fn shr_assign(&mut self, rhs: usize) {
self.0 >>= rhs;
}
}
impl Not for Bitmap8 {
type Output = Self;
fn not(self) -> Self::Output {
Self(self.0 ^ u8::MAX)
}
}
impl Deref for Bitmap8 {
type Target = u8;
fn deref(&self) -> &Self::Target {
&self.0
}
}