use core::fmt;
use super::*;
#[cfg(feature = "proptest")]
use proptest::{arbitrary::Arbitrary, strategy::{self, Strategy}};
macro_rules! impl_mask_elem {
{ $(
$(#[$attr:meta])*
$vis:vis type $name:ident($base:ty);
)* } => { $(
$(#[$attr])*
#[derive(Copy, Clone)]
#[repr(transparent)]
$vis struct $name($base);
impl $name {
pub const fn new(value: bool) -> Self {
Self(if value { -1 } else { 0 })
}
pub const fn value(self) -> bool {
self.0 < 0
}
pub const ACTIVE: Self = Self(-1);
pub const INACTIVE: Self = Self(0);
}
unsafe impl<const LEN: usize> Element<LEN> for $name
where $base: Element<LEN> {
type Primitive = <$base as Element<LEN>>::Primitive;
}
impl From<bool> for $name {
fn from(value: bool) -> Self {
Self::new(value)
}
}
impl From<$name> for bool {
fn from(value: $name) -> Self {
value.value()
}
}
impl From<$base> for $name {
fn from(value: $base) -> Self {
Self::new(value < 0)
}
}
impl From<$name> for $base {
fn from(value: $name) -> Self {
value.0
}
}
impl PartialEq for $name {
fn eq(&self, that: &Self) -> bool {
self.value() == that.value()
}
}
impl Eq for $name {}
impl fmt::Debug for $name {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_tuple(stringify!($name))
.field(&self.value())
.finish()
}
}
#[cfg(feature = "proptest")]
impl Arbitrary for $name {
type Parameters = ();
type Strategy = strategy::MapInto<
<bool as Arbitrary>::Strategy, $name>;
fn arbitrary_with((): Self::Parameters) -> Self::Strategy {
bool::arbitrary_with(()).prop_map_into()
}
}
)* };
}
impl_mask_elem! {
pub type Mask8(i8);
pub type Mask16(i16);
pub type Mask32(i32);
pub type Mask64(i64);
}