use std::ops::{Deref, DerefMut};
pub use binf_macros::*;
pub trait BitFlag {
type T;
fn set_flag(&mut self, position: u8, value: bool);
fn get_flag(&self, position: u8) -> bool;
fn flags(&self) -> Self::T;
fn set_flags(&mut self, flags: &[bool]);
}
impl BitFlag for u8 {
type T = [bool; 8];
fn set_flag(&mut self, position: u8, value: bool) {
if value {
*self |= 1 << position;
} else {
*self &= !(1 << position);
}
}
fn get_flag(&self, position: u8) -> bool {
(*self & (1 << position)) != 0
}
fn flags(&self) -> Self::T {
let mut flags = [false; 8];
for (i, flag) in flags.iter_mut().enumerate() {
*flag = self.get_flag(i as u8);
}
flags
}
fn set_flags(&mut self, flags: &[bool]) {
for (i, v) in flags.iter().enumerate() {
if i >= 8 {
break;
}
self.set_flag(i as u8, *v);
}
}
}
impl BitFlag for u16 {
type T = [bool; 16];
fn set_flag(&mut self, position: u8, value: bool) {
if value {
*self |= 1 << position;
} else {
*self &= !(1 << position);
}
}
fn get_flag(&self, position: u8) -> bool {
(*self & (1 << position)) != 0
}
fn flags(&self) -> Self::T {
let mut flags = [false; 16];
for (i, flag) in flags.iter_mut().enumerate() {
*flag = self.get_flag(i as u8);
}
flags
}
fn set_flags(&mut self, flags: &[bool]) {
for (i, v) in flags.iter().enumerate() {
if i >= 16 {
break;
}
self.set_flag(i as u8, *v);
}
}
}
impl BitFlag for u32 {
type T = [bool; 32];
fn set_flag(&mut self, position: u8, value: bool) {
if value {
*self |= 1 << position;
} else {
*self &= !(1 << position);
}
}
fn get_flag(&self, position: u8) -> bool {
(*self & (1 << position)) != 0
}
fn flags(&self) -> Self::T {
let mut flags = [false; 32];
for (i, flag) in flags.iter_mut().enumerate() {
*flag = self.get_flag(i as u8);
}
flags
}
fn set_flags(&mut self, flags: &[bool]) {
for (i, v) in flags.iter().enumerate() {
if i >= 32 {
break;
}
self.set_flag(i as u8, *v);
}
}
}
impl BitFlag for u64 {
type T = [bool; 64];
fn set_flag(&mut self, position: u8, value: bool) {
if value {
*self |= 1 << position;
} else {
*self &= !(1 << position);
}
}
fn get_flag(&self, position: u8) -> bool {
(*self & (1 << position)) != 0
}
fn flags(&self) -> Self::T {
let mut flags = [false; 64];
for (i, flag) in flags.iter_mut().enumerate() {
*flag = self.get_flag(i as u8);
}
flags
}
fn set_flags(&mut self, flags: &[bool]) {
for (i, v) in flags.iter().enumerate() {
if i >= 64 {
break;
}
self.set_flag(i as u8, *v);
}
}
}
impl BitFlag for u128 {
type T = [bool; 128];
fn set_flag(&mut self, position: u8, value: bool) {
if value {
*self |= 1 << position;
} else {
*self &= !(1 << position);
}
}
fn get_flag(&self, position: u8) -> bool {
(*self & (1 << position)) != 0
}
fn flags(&self) -> Self::T {
let mut flags = [false; 128];
for (i, flag) in flags.iter_mut().enumerate() {
*flag = self.get_flag(i as u8);
}
flags
}
fn set_flags(&mut self, flags: &[bool]) {
for (i, v) in flags.iter().enumerate() {
if i >= 128 {
break;
}
self.set_flag(i as u8, *v);
}
}
}
pub struct BitFlags<T>(T);
impl<T: BitFlag> BitFlags<T> {
pub fn new(value: T) -> Self {
Self(value)
}
pub fn set_flag(&mut self, position: u8, value: bool) {
self.0.set_flag(position, value);
}
pub fn get_flag(&self, position: u8) -> bool {
self.0.get_flag(position)
}
pub fn flags(&self) -> T::T {
self.0.flags()
}
pub fn set_flags(&mut self, flags: &[bool]) {
self.0.set_flags(flags);
}
}
impl<T: BitFlag> Deref for BitFlags<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<T: BitFlag> DerefMut for BitFlags<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}