use core::marker::PhantomData;
use core::str::FromStr;
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub enum Endian {
Little,
Big,
}
#[derive(Debug, Copy, Clone, Eq, PartialEq, Default)]
pub enum Order {
#[default]
Msb0,
Lsb0,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ParseEndianError {}
impl Endian {
#[inline]
pub const fn new() -> Self {
#[cfg(target_endian = "little")]
let endian = Endian::Little;
#[cfg(target_endian = "big")]
let endian = Endian::Big;
endian
}
#[inline]
pub fn is_le(self) -> bool {
self == Endian::Little
}
#[inline]
pub fn is_be(self) -> bool {
self == Endian::Big
}
}
impl Default for Endian {
#[inline]
fn default() -> Self {
Self::new()
}
}
impl FromStr for Endian {
type Err = ParseEndianError;
#[inline]
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"little" => Ok(Endian::Little),
"big" => Ok(Endian::Big),
_ => Err(ParseEndianError {}),
}
}
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Ord, PartialOrd)]
pub enum Limit<T, Predicate: FnMut(&T) -> bool> {
Count(usize),
Until(Predicate, PhantomData<T>),
ByteSize(ByteSize),
BitSize(BitSize),
End,
}
impl<T> From<usize> for Limit<T, fn(&T) -> bool> {
#[inline]
fn from(n: usize) -> Self {
Limit::Count(n)
}
}
impl<T, Predicate: for<'a> FnMut(&'a T) -> bool> From<Predicate> for Limit<T, Predicate> {
#[inline]
fn from(predicate: Predicate) -> Self {
Limit::Until(predicate, PhantomData)
}
}
impl<T> From<ByteSize> for Limit<T, fn(&T) -> bool> {
#[inline]
fn from(size: ByteSize) -> Self {
Limit::ByteSize(size)
}
}
impl<T> From<BitSize> for Limit<T, fn(&T) -> bool> {
#[inline]
fn from(size: BitSize) -> Self {
Limit::BitSize(size)
}
}
impl<T, Predicate: for<'a> FnMut(&'a T) -> bool> Limit<T, Predicate> {
#[inline]
pub fn new_until(predicate: Predicate) -> Self {
predicate.into()
}
}
impl<T> Limit<T, fn(&T) -> bool> {
#[inline]
pub fn end() -> Self {
Self::End
}
}
impl<T> Limit<T, fn(&T) -> bool> {
#[inline]
pub fn new_count(count: usize) -> Self {
count.into()
}
#[inline]
pub fn new_bit_size(size: BitSize) -> Self {
size.into()
}
#[inline]
pub fn new_byte_size(size: ByteSize) -> Self {
size.into()
}
}
#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
pub struct ByteSize(pub usize);
#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
pub struct BitSize(pub usize);
impl BitSize {
#[inline]
const fn bits_from_reader(byte_size: usize) -> Self {
Self(byte_size * 8)
}
#[inline]
pub const fn of<T>() -> Self {
Self::bits_from_reader(core::mem::size_of::<T>())
}
#[inline]
pub fn of_val<T: ?Sized>(val: &T) -> Self {
Self::bits_from_reader(core::mem::size_of_val(val))
}
}
pub struct ReadExact(pub usize);