big updates v1 rc1

This commit is contained in:
davidon-top 2023-10-06 21:51:59 +02:00
parent 503f52b60a
commit 48b1ffeb99
11 changed files with 387 additions and 101 deletions

View file

@ -1,26 +0,0 @@
pub fn get_flags(flags: i32) -> Vec<i32> {
let mut fvec: Vec<bool> = Vec::new();
let mut rest = flags;
while rest != 0 {
fvec.push((rest % 2) != 0);
rest = rest / 2;
}
let mut tvec: Vec<i32> = Vec::new();
for (i, value) in fvec.iter().enumerate() {
if *value {
tvec.push(i as i32);
}
}
tvec
}
pub fn vec_to_flag(vec: Vec<bool>) -> u128 {
let mut flag = 0;
for (i, &val) in vec.iter().enumerate() {
if val {
flag |= 1 << i;
}
}
flag
}

213
src/lib.rs Normal file → Executable file
View file

@ -1,66 +1,187 @@
/*!
TODO documentation
# binf, Binary flags
This crate aims to make working with binary/bit flags easier. It also provides a macro to add similar functionality to zig's packed structs with boolean fields.
*/
pub mod flag_utils;
pub mod macros;
pub use binf_macros::*;
#[cfg(test)]
mod test;
mod tests;
///struct that holds data for a flag and useful functions
pub struct Flag {
value: u128,
/// A trait for types that can be used as bit flags.
pub trait BitFlag {
type T;
/// Sets the flag at the given position to the given value.
/// I don't know what happens if the position is larger than the number of bits in the type.
fn set_flag(&mut self, position: u8, value: bool);
/// Returns the value of the flag at the given position.
/// I don't know what happens if the position is larger than the number of bits in the type.
fn get_flag(&self, position: u8) -> bool;
/// Returns an array of bools representing the flags.
/// The first element in the array is the flag at position 0.
fn flags(&self) -> Self::T;
/// Sets the flags to the given values.
/// flags can be any size, but if it is larger than the number of bits in the type only the first bits will be used.
/// So if this is u8 flags should be 8 or less any more are ignored.
fn set_flags(&mut self, flags: &[bool]);
}
impl Flag {
/// set a flag value
pub fn set_flag(&mut self, flag: u128, value: bool) {
/// implementation for u8. u8 means it can store 8 flags 1 flag per bit.
impl BitFlag for u8 {
type T = [bool; 8];
fn set_flag(&mut self, position: u8, value: bool) {
if value {
self.value |= 1 << flag;
*self |= 1 << position;
} else {
self.value &= !(1 << flag);
*self &= !(1 << position);
}
}
/// get a value of flag
pub fn get_flag(&self, flag: u32) -> bool {
(self.value & (1 << flag)) != 0
fn get_flag(&self, position: u8) -> bool {
(*self & (1 << position)) != 0
}
/// returns a vector with all enabled flags
pub fn get_all_flags(&self) -> Vec<bool> {
let mut ret = vec![];
for i in 0..128 {
ret.push(&self.value & (1 << i) != 0);
fn flags(&self) -> Self::T {
let mut flags = [false; 8];
for i in 0..8 {
flags[i] = self.get_flag(i as u8);
}
for i in (0..ret.len()).rev() {
if ret[i] {
ret.truncate(i + 1);
flags
}
fn set_flags(&mut self, flags: &[bool]) {
for (i, v) in flags.into_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 in 0..16 {
flags[i] = self.get_flag(i as u8);
}
flags
}
fn set_flags(&mut self, flags: &[bool]) {
for (i, v) in flags.into_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 in 0..32 {
flags[i] = self.get_flag(i as u8);
}
flags
}
fn set_flags(&mut self, flags: &[bool]) {
for (i, v) in flags.into_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 in 0..64 {
flags[i] = self.get_flag(i as u8);
}
flags
}
fn set_flags(&mut self, flags: &[bool]) {
for (i, v) in flags.into_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 in 0..128 {
flags[i] = self.get_flag(i as u8);
}
flags
}
fn set_flags(&mut self, flags: &[bool]) {
for (i, v) in flags.into_iter().enumerate() {
if i >= 128 {
break;
}
self.set_flag(i as u8, *v);
}
ret
}
/// creates Flag from int
pub fn new_from_value(value: u128) -> Self {
Self {value}
}
/// returns flags value
pub fn get(&self) -> u128 {
self.value
}
/// sets internal value to this
pub fn set_value(&mut self, value: u128) {
self.value = value;
}
/// initializes a Flag with 0, use flag_new! macro to create with flags instead
pub fn new() -> Self {
Self { value: 0, }
}
}

View file

@ -1,15 +0,0 @@
//#[macro_use]
/// macro that creates new Flag
/// for example: flag_new![3, 7] makes a flag that has those flags enabled (136)
#[macro_export]
macro_rules! flag_new {
( $($f:expr),* ) => {
{
let mut tflag = crate::Flag::new();
$(
tflag.set_flag($f, true);
)*
tflag
}
}
}

View file

@ -1,11 +0,0 @@
use crate::{flag_new, Flag, flag_utils:: vec_to_flag};
#[test]
fn all() {
let flag = flag_new![3, 7];
assert_eq!(flag.get(), 136);
assert_eq!(flag.get_flag(3), true);
assert_eq!(flag.get_flag(4), false);
assert_eq!(flag.get_all_flags(), vec![false, false, false, true, false, false, false, true]);
assert_eq!(vec_to_flag(vec![false, false, false, true, false, false, false, true]), flag.get());
}

71
src/tests.rs Normal file
View file

@ -0,0 +1,71 @@
use crate::*;
#[bitflag]
pub struct Test {
a: bool,
b: bool,
c: bool,
d: bool,
e: bool,
f: bool,
g: bool,
h: bool,
}
#[test]
fn macro_test() {
let mut test = Test::new(0b10101010);
assert_eq!(test.a(), false);
assert_eq!(test.b(), true);
assert_eq!(test.c(), false);
assert_eq!(test.d(), true);
assert_eq!(test.e(), false);
assert_eq!(test.f(), true);
assert_eq!(test.g(), false);
assert_eq!(test.h(), true);
}
#[test]
fn macro_test_set() {
let mut test = Test::new(0b10101010);
test.set_a(true);
test.set_b(false);
test.set_c(true);
test.set_d(false);
test.set_e(true);
test.set_f(false);
test.set_g(true);
test.set_h(false);
assert_eq!(test.value(), 0b01010101);
}
#[test]
fn macro_test_iter() {
let test = Test::new(0b10101010);
let flags = test.flags();
let mut iter = flags.iter();
assert_eq!(iter.next(), Some(false).as_ref());
assert_eq!(iter.next(), Some(true).as_ref());
assert_eq!(iter.next(), Some(false).as_ref());
assert_eq!(iter.next(), Some(true).as_ref());
assert_eq!(iter.next(), Some(false).as_ref());
assert_eq!(iter.next(), Some(true).as_ref());
assert_eq!(iter.next(), Some(false).as_ref());
assert_eq!(iter.next(), Some(true).as_ref());
assert_eq!(iter.next(), None);
}
#[test]
fn u64_test() {
let mut flags = 0b10101010u64;
assert_eq!(flags.get_flag(0), false);
assert_eq!(flags.get_flag(1), true);
assert_eq!(flags.get_flag(2), false);
assert_eq!(flags.get_flag(3), true);
assert_eq!(flags.get_flag(4), false);
assert_eq!(flags.get_flag(5), true);
assert_eq!(flags.get_flag(6), false);
assert_eq!(flags.get_flag(7), true);
flags.set_flag(0, true);
assert_eq!(flags, 0b10101011);
}