Skip to content

Commit

Permalink
core: semplify the fundamentals implementation
Browse files Browse the repository at this point in the history
Signed-off-by: Vincenzo Palazzo <[email protected]>
  • Loading branch information
vincenzopalazzo committed Jul 26, 2024
1 parent 107aebd commit b81e336
Showing 1 changed file with 5 additions and 70 deletions.
75 changes: 5 additions & 70 deletions fundamentals/src/bitflag.rs
Original file line number Diff line number Diff line change
@@ -1,92 +1,27 @@
//! Bitflag rust Implementation.
//!
//! This implementation is inspired and taken from
//! the awesome amplify library <https://github.com/rust-amplify/rust-amplify/blob/master/src/collection/flags.rs>
//!
//! Author: Vincenzo Palazzo <[email protected]>.
use std::vec::Vec;

use crate::core::{FromWire, ToWire};

#[derive(Clone)]
// FIXME: rename to bitvector :)
#[derive(Clone, Debug)]
pub struct BitFlag {
pub len: u16,
inner: Vec<u8>,
}

impl BitFlag {
fn bits_to_bytes(bits: usize) -> usize {
if bits == 0 {
0
} else {
(bits / 8 + 1) as usize
}
}

fn trim(&self) -> Vec<u8> {
if self.inner.is_empty() {
return Vec::new();
}
let buff = self.inner.clone();
let size = buff.len();
let mut top = 0;
while top < size && !self.is_set(size - top) {
top += 1;
}
let top = size - top;
let used = Self::bits_to_bytes(top);
if used < size {
let mut sub_buff = vec![0u8; used];
sub_buff.copy_from_slice(&self.inner[..used]);
return sub_buff;
}
buff
}

/// Returns whether a feature flag with `flag_no` is set (`true` or `false`)
#[inline]
pub fn is_set(&self, flag_no: usize) -> bool {
self.byte_at(flag_no)
.map(|byte| (byte & (1 << (flag_no % 8))) > 0)
.unwrap_or(false)
}

/// Returns reference to the byte responsible for the feature flag
/// `flag_no`. If the maximum capacity is exceeded, returns
/// [`Option::None`].
#[inline]
fn byte_at(&self, flag_no: usize) -> Option<&u8> {
if flag_no >= self.inner.len() {
return None;
}
Some(&self.inner[flag_no as usize / 8])
}
}

impl std::fmt::Debug for BitFlag {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
writeln!(f, "{{")?;
writeln!(f, " len: {:?}", self.len)?;
writeln!(f, " hex: {:x}", self)?;
write!(f, "}}")
}
}

impl std::fmt::LowerHex for BitFlag {
fn fmt(&self, fmtr: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
for byte in self.inner.iter() {
fmtr.write_fmt(format_args!("{:02x}", byte))?;
}
Ok(())
pub fn to_slice(&self) -> &[u8] {
&self.inner
}
}

impl ToWire for BitFlag {
fn to_wire<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<()> {
let feature = self.trim();

self.len.to_wire(writer)?;
writer.write_all(&feature)?;
writer.write_all(&self.inner)?;
Ok(())
}
}
Expand Down

0 comments on commit b81e336

Please sign in to comment.