use core::{cmp::Ordering, fmt, num::TryFromIntError};
#[cfg(all(feature = "alloc", not(feature = "std")))]
use alloc::{vec, vec::Vec};
#[cfg(feature = "std")]
use std::{vec, vec::Vec};
#[derive(Debug, Copy, Clone, Eq, Hash, PartialEq, PartialOrd, Ord)]
pub struct Index(pub u32);
impl Index {
#[inline]
#[must_use]
pub fn prev(&self) -> Option<Index> {
self.0.checked_sub(1).map(Index)
}
}
impl From<u32> for Index {
fn from(value: u32) -> Self {
Index(value)
}
}
impl From<Index> for u32 {
fn from(value: Index) -> Self {
value.0
}
}
impl From<Index> for u64 {
fn from(value: Index) -> Self {
u64::from(value.0)
}
}
impl fmt::Display for Index {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.0)
}
}
#[derive(Debug, Copy, Clone, Eq, Hash, PartialEq, PartialOrd, Ord)]
pub struct Length(pub u32);
impl From<u32> for Length {
fn from(value: u32) -> Self {
Length(value)
}
}
impl From<Length> for u32 {
fn from(value: Length) -> Self {
value.0
}
}
impl From<Length> for u64 {
fn from(value: Length) -> Self {
u64::from(value.0)
}
}
impl TryFrom<Length> for usize {
type Error = TryFromIntError;
fn try_from(value: Length) -> Result<Self, Self::Error> {
usize::try_from(value.0)
}
}
impl fmt::Display for Length {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.0)
}
}
impl PartialEq<BlockBegin> for Length {
fn eq(&self, other: &BlockBegin) -> bool {
self.0 == other.0
}
}
impl PartialOrd<BlockBegin> for Length {
fn partial_cmp(&self, other: &BlockBegin) -> Option<Ordering> {
Some(self.0.cmp(&other.0))
}
}
#[derive(Debug, Copy, Clone, Eq, Hash, PartialEq, PartialOrd, Ord)]
pub struct BlockBegin(pub u32);
impl BlockBegin {
#[must_use]
pub const fn index(&self) -> u32 {
self.0 / BlockLength::MAX
}
}
impl From<u32> for BlockBegin {
fn from(value: u32) -> Self {
BlockBegin(value)
}
}
impl From<BlockBegin> for u32 {
fn from(value: BlockBegin) -> Self {
value.0
}
}
impl From<BlockBegin> for u64 {
fn from(value: BlockBegin) -> Self {
u64::from(value.0)
}
}
impl TryFrom<BlockBegin> for usize {
type Error = TryFromIntError;
fn try_from(value: BlockBegin) -> Result<Self, Self::Error> {
usize::try_from(value.0)
}
}
impl PartialEq<Length> for BlockBegin {
fn eq(&self, other: &Length) -> bool {
self.0 == other.0
}
}
impl PartialOrd<Length> for BlockBegin {
fn partial_cmp(&self, other: &Length) -> Option<Ordering> {
Some(self.0.cmp(&other.0))
}
}
impl fmt::Display for BlockBegin {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.0.fmt(f)
}
}
#[derive(Debug, Copy, Clone, Eq, Hash, PartialEq, PartialOrd, Ord)]
pub struct BlockLength(pub u32);
impl From<u32> for BlockLength {
fn from(value: u32) -> Self {
BlockLength(value)
}
}
impl From<BlockLength> for u32 {
fn from(value: BlockLength) -> Self {
value.0
}
}
impl From<BlockLength> for u64 {
fn from(value: BlockLength) -> Self {
u64::from(value.0)
}
}
impl TryFrom<BlockLength> for usize {
type Error = TryFromIntError;
fn try_from(value: BlockLength) -> Result<Self, Self::Error> {
usize::try_from(value.0)
}
}
impl BlockLength {
pub const MAX: u32 = 16384;
pub const MAX_USIZE: usize = 16384;
#[must_use]
pub const fn max() -> Self {
BlockLength(16384)
}
#[must_use]
pub const fn is_greater_than_max(&self) -> bool {
self.0 > Self::MAX
}
}
impl fmt::Display for BlockLength {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.0.fmt(f)
}
}
#[derive(Debug, Copy, Clone, Eq, Hash, PartialEq, PartialOrd, Ord)]
pub struct Block {
pub index: Index,
pub begin: BlockBegin,
pub length: BlockLength,
}
impl From<(Index, BlockBegin, BlockLength)> for Block {
fn from(value: (Index, BlockBegin, BlockLength)) -> Self {
Block::new(value.0, value.1, value.2)
}
}
impl Block {
#[must_use]
pub const fn new(index: Index, begin: BlockBegin, length: BlockLength) -> Self {
Self {
index,
begin,
length,
}
}
}
#[derive(Clone, PartialEq, Eq)]
pub struct BlockData<'a> {
pub index: Index,
pub begin: BlockBegin,
pub data: &'a [u8],
}
impl<'a> From<(Index, BlockBegin, &'a [u8])> for BlockData<'a> {
fn from(value: (Index, BlockBegin, &'a [u8])) -> Self {
BlockData::new(value.0, value.1, value.2)
}
}
impl<'a> BlockData<'a> {
#[must_use]
pub const fn new(index: Index, begin: BlockBegin, data: &'a [u8]) -> Self {
Self { index, begin, data }
}
#[must_use]
pub fn to_block(&self) -> Block {
Block {
index: self.index,
begin: self.begin,
length: BlockLength::from(u32::try_from(self.data.len()).unwrap()),
}
}
}
impl<'a> fmt::Debug for BlockData<'a> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("BlockData")
.field("index", &self.index)
.field("begin", &self.begin)
.field("data.len", &self.data.len())
.finish()
}
}
#[derive(Debug)]
#[cfg_attr(feature = "std", derive(thiserror::Error))]
#[cfg_attr(feature = "std", error("invalid bitfield"))]
pub struct InvalidBitfieldError;
#[cfg(feature = "std")]
impl From<InvalidBitfieldError> for std::io::Error {
fn from(error: InvalidBitfieldError) -> Self {
std::io::Error::new(std::io::ErrorKind::InvalidData, error)
}
}
pub fn verify_bitfield<T: AsRef<[u8]>>(
max_index: Index,
bitfield: T,
) -> Result<(), InvalidBitfieldError> {
let bitfield = bitfield.as_ref();
let expected_bitfield_len =
usize::try_from(max_index.0 / 8 + u32::from(max_index.0 % 8 != 0)).unwrap();
if bitfield.len() != expected_bitfield_len {
return Err(InvalidBitfieldError);
}
let remainder = usize::try_from(max_index.0 % 8).unwrap();
if remainder != 0 {
if let Some(last_byte) = bitfield.last() {
for offset in remainder..8 {
if (last_byte & 0x80 >> offset) != 0 {
return Err(InvalidBitfieldError);
}
}
} else {
return Err(InvalidBitfieldError);
}
}
Ok(())
}
use bitvec::prelude::*;
#[derive(Debug, Clone, Eq, Hash, PartialEq, PartialOrd, Ord)]
pub struct IndexBitfield(BitVec<u8, Msb0>);
impl IndexBitfield {
#[must_use]
pub fn with_max_index(max_index: Index) -> Self {
let len = usize::try_from(max_index.0).unwrap();
Self(bitvec![u8, Msb0; 0; len])
}
pub fn clear_with_max_index(&mut self, max_index: Index) {
self.0.clear();
self.0.resize(usize::try_from(max_index.0).unwrap(), false);
}
#[must_use]
pub fn max_index(&self) -> Index {
Index::from(u32::try_from(self.0.len()).unwrap())
}
#[must_use]
pub fn from_slice(bitfield: &[u8], max_index: Index) -> Self {
let mut bitfield = BitVec::from_slice(bitfield);
bitfield.resize(usize::try_from(max_index.0).unwrap(), false);
Self(bitfield)
}
#[must_use]
pub fn as_raw_slice(&self) -> &[u8] {
self.0.as_raw_slice()
}
#[must_use]
pub fn get(&self, index: Index) -> bool {
*self.0.get(usize::try_from(index.0).unwrap()).unwrap()
}
pub fn set(&mut self, index: Index, value: bool) {
*self.0.get_mut(usize::try_from(index.0).unwrap()).unwrap() = value;
}
#[must_use]
pub fn not_any(&self) -> bool {
self.0.not_any()
}
#[must_use]
pub fn not_all_set(&self) -> bool {
self.0.not_all()
}
#[must_use]
pub fn all_set(&self) -> bool {
self.0.all()
}
pub fn iter_set(&self) -> impl Iterator<Item = Index> + '_ {
self.0
.iter_ones()
.map(|index| u32::try_from(index).unwrap())
.map(Index)
}
#[cfg(test)]
fn iter_not_set(&self) -> impl Iterator<Item = Index> + '_ {
self.0
.iter_zeros()
.map(|index| u32::try_from(index).unwrap())
.map(Index)
}
#[must_use]
pub fn difference(self, other: IndexBitfield) -> IndexBitfield {
let orig = self.0;
let not_other = !other.0;
IndexBitfield(orig & not_other)
}
#[must_use]
pub fn is_superset(&self, other: &IndexBitfield) -> bool {
assert_eq!(self.0.len(), other.0.len());
for index in other.0.iter_ones() {
if !*self.0.get(index).unwrap() {
return false;
}
}
true
}
#[must_use]
pub fn is_subset(&self, other: &IndexBitfield) -> bool {
assert_eq!(self.0.len(), other.0.len());
for index in self.0.iter_ones() {
if !*other.0.get(index).unwrap() {
return false;
}
}
true
}
}
pub trait UnsignedInt: Sized + sealed::Private {
#[must_use]
fn inc(&self) -> Self;
#[must_use]
fn dec(&self) -> Self;
}
#[derive(Debug)]
pub struct IndexCountedSet<T>(Vec<T>);
impl<T> IndexCountedSet<T>
where
T: UnsignedInt,
{
#[must_use]
pub fn new(max_index: Index) -> Self
where
T: Clone + Default,
{
let len = usize::try_from(max_index.0).unwrap();
Self(vec![T::default(); len])
}
#[must_use]
pub fn max_index(&self) -> Index {
Index::from(u32::try_from(self.0.len()).unwrap())
}
pub fn inc(&mut self, index: Index)
where
T:,
{
let index = usize::try_from(index.0).unwrap();
self.0[index] = self.0[index].inc();
}
pub fn inc_bitfield(&mut self, bitfield: &IndexBitfield) {
debug_assert_eq!(self.0.len(), bitfield.0.len());
for index in bitfield.0.iter_ones() {
self.0[index] = self.0[index].inc();
}
}
pub fn dec(&mut self, index: Index) {
let index = usize::try_from(index.0).unwrap();
self.0[index] = self.0[index].dec();
}
pub fn dec_bitfield(&mut self, bitfield: &IndexBitfield) {
debug_assert_eq!(self.0.len(), bitfield.0.len());
for index in bitfield.0.iter_ones() {
self.0[index] = self.0[index].dec();
}
}
pub fn reset(&mut self, index: Index)
where
T: Default,
{
let index = usize::try_from(index.0).unwrap();
self.0[index] = T::default();
}
pub fn count(&mut self, index: Index) -> T
where
T: Copy,
{
let index = usize::try_from(index.0).unwrap();
self.0[index]
}
pub fn nonzero_iter(&self) -> impl Iterator<Item = Index> + '_
where
T: Copy + Default + PartialOrd,
{
self.0
.iter()
.enumerate()
.filter(|(_, &req_count)| req_count > T::default())
.map(|(index, _)| Index::from(u32::try_from(index).unwrap()))
}
}
mod sealed {
pub trait Private {}
macro_rules! unsigned_int_impl {
($ty:ty) => {
impl Private for $ty {}
impl super::UnsignedInt for $ty {
fn inc(&self) -> Self {
self.checked_add(1).unwrap()
}
fn dec(&self) -> Self {
self.checked_sub(1).unwrap()
}
}
};
}
unsigned_int_impl!(u8);
unsigned_int_impl!(u16);
unsigned_int_impl!(u32);
unsigned_int_impl!(u64);
unsigned_int_impl!(usize);
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_index_bitfield_max_index() {
let max_piece_index = Index(9);
let pieces_set = IndexBitfield::with_max_index(max_piece_index);
assert_eq!(pieces_set.max_index(), Index(9));
let pieces_set = IndexBitfield::from_slice(&[0; 2], Index(9));
assert_eq!(pieces_set.max_index(), Index(9));
assert_eq!(pieces_set.as_raw_slice(), &[0, 0]);
let pieces_set = IndexBitfield::from_slice(&[0xFE; 20], Index(9));
assert_eq!(pieces_set.max_index(), Index(9));
assert_eq!(pieces_set.as_raw_slice(), &[0xFE, 0xFE]);
}
#[test]
fn test_index_set() {
let max_piece_index = Index(9);
let mut pieces_set = IndexBitfield::with_max_index(max_piece_index);
assert_eq!(pieces_set.0.as_raw_slice().len(), 2);
assert_eq!(pieces_set.as_raw_slice()[0], 0x0);
assert_eq!(pieces_set.as_raw_slice()[1], 0x0);
assert_eq!(pieces_set.iter_set().count(), 0);
assert_eq!(pieces_set.iter_not_set().count(), 9);
assert!(!pieces_set.get(Index(3)));
pieces_set.set(Index(3), true);
assert_eq!(pieces_set.as_raw_slice()[0], 0x10);
assert_eq!(pieces_set.as_raw_slice()[1], 0x00);
assert!(pieces_set.get(Index(3)));
assert_eq!(pieces_set.iter_set().count(), 1);
assert_eq!(pieces_set.iter_not_set().count(), 8);
assert!(!pieces_set.get(Index(8)));
pieces_set.set(Index(8), true);
assert_eq!(pieces_set.as_raw_slice()[0], 0x10);
assert_eq!(pieces_set.as_raw_slice()[1], 0x80);
assert!(pieces_set.get(Index(8)));
assert_eq!(pieces_set.iter_set().count(), 2);
assert_eq!(pieces_set.iter_not_set().count(), 7);
assert!(pieces_set.get(Index(8)));
pieces_set.set(Index(8), false);
assert_eq!(pieces_set.as_raw_slice()[0], 0x10);
assert_eq!(pieces_set.as_raw_slice()[1], 0x00);
assert!(!pieces_set.get(Index(8)));
assert_eq!(pieces_set.iter_set().count(), 1);
assert_eq!(pieces_set.iter_not_set().count(), 8);
}
#[test]
fn test_index_set_is_superset() {
let mut pieces_set1 = IndexBitfield::with_max_index(Index(9));
let mut pieces_set2 = IndexBitfield::with_max_index(Index(9));
assert!(pieces_set1.is_superset(&pieces_set2));
assert!(pieces_set2.is_superset(&pieces_set1));
pieces_set1.set(Index(1), true);
assert!(pieces_set1.is_superset(&pieces_set2));
assert!(!pieces_set2.is_superset(&pieces_set1));
pieces_set2.set(Index(1), true);
assert!(pieces_set1.is_superset(&pieces_set2));
assert!(pieces_set2.is_superset(&pieces_set1));
pieces_set1.set(Index(4), true);
pieces_set1.set(Index(8), true);
assert!(pieces_set1.is_superset(&pieces_set2));
assert!(!pieces_set2.is_superset(&pieces_set1));
pieces_set2.set(Index(4), true);
assert!(pieces_set1.is_superset(&pieces_set2));
assert!(!pieces_set2.is_superset(&pieces_set1));
pieces_set2.set(Index(8), true);
assert!(pieces_set1.is_superset(&pieces_set2));
assert!(pieces_set2.is_superset(&pieces_set1));
pieces_set2.set(Index(7), true);
assert!(!pieces_set1.is_superset(&pieces_set2));
assert!(pieces_set2.is_superset(&pieces_set1));
pieces_set1.set(Index(6), true);
assert!(!pieces_set1.is_superset(&pieces_set2));
assert!(!pieces_set2.is_superset(&pieces_set1));
}
#[test]
fn test_index_set_is_subset() {
let mut pieces_set1 = IndexBitfield::with_max_index(Index(9));
let mut pieces_set2 = IndexBitfield::with_max_index(Index(9));
assert!(pieces_set1.is_subset(&pieces_set2));
assert!(pieces_set2.is_subset(&pieces_set1));
pieces_set1.set(Index(1), true);
assert!(!pieces_set1.is_subset(&pieces_set2));
assert!(pieces_set2.is_subset(&pieces_set1));
pieces_set2.set(Index(1), true);
assert!(pieces_set1.is_subset(&pieces_set2));
assert!(pieces_set2.is_subset(&pieces_set1));
pieces_set1.set(Index(4), true);
pieces_set1.set(Index(8), true);
assert!(!pieces_set1.is_subset(&pieces_set2));
assert!(pieces_set2.is_subset(&pieces_set1));
pieces_set2.set(Index(4), true);
assert!(!pieces_set1.is_subset(&pieces_set2));
assert!(pieces_set2.is_subset(&pieces_set1));
pieces_set2.set(Index(8), true);
assert!(pieces_set1.is_subset(&pieces_set2));
assert!(pieces_set2.is_subset(&pieces_set1));
pieces_set2.set(Index(7), true);
assert!(pieces_set1.is_subset(&pieces_set2));
assert!(!pieces_set2.is_subset(&pieces_set1));
pieces_set1.set(Index(6), true);
assert!(!pieces_set1.is_subset(&pieces_set2));
assert!(!pieces_set2.is_subset(&pieces_set1));
}
}