mimesis 0.2.0

Generate 3D meshes from images using contour tracing and polygon extrusion.
Documentation
use std::num::ParseIntError;
use std::ops::{Add, AddAssign, BitAnd, BitOr, BitXor, Deref, Div, DivAssign, Mul, MulAssign, Not, Rem, Sub, SubAssign};
use image::{Pixel, Primitive};
use num_traits::{Bounded, Num, NumCast, One, ToPrimitive, Zero};

#[repr(transparent)]
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Bit(pub bool);

impl Deref for Bit {
    type Target = bool;

    fn deref(&self) -> &Self::Target {
        &self.0
    }
}

impl From<bool> for Bit {
    fn from(value: bool) -> Self {
        Bit(value)
    }
}

impl AddAssign for Bit {
    fn add_assign(&mut self, rhs: Self) {
        *self = *self + rhs;
    }
}

impl SubAssign for Bit {
    fn sub_assign(&mut self, rhs: Self) {
        *self = *self - rhs;
    }
}

impl MulAssign for Bit {
    fn mul_assign(&mut self, rhs: Self) {
        *self = *self * rhs;
    }
}

impl DivAssign for Bit {
    fn div_assign(&mut self, rhs: Self) {
        *self = *self / rhs;
    }
}

impl Add for Bit {
    type Output = Self;
    fn add(mut self, rhs: Self) -> Self::Output {
        self.0 |= *rhs;
        self
    }
}

impl Sub for Bit {
    type Output = Self;
    fn sub(mut self, rhs: Self) -> Self::Output {
        self.0 ^= *rhs;
        self
    }
}

impl Mul for Bit {
    type Output = Self;
    fn mul(mut self, rhs: Self) -> Self::Output {
        self.0 &= *rhs;
        self
    }
}

impl Div for Bit {
    type Output = Self;
    fn div(mut self, rhs: Self) -> Self::Output {
        debug_assert!(*rhs, "Cannot divide by zero");
        self.0 &= *rhs;
        self
    }
}

impl Rem for Bit {
    type Output = Self;
    fn rem(self, rhs: Self) -> Self::Output {
        debug_assert!(*rhs, "Cannot divide by zero");
        Self(false)
    }
}

impl BitOr for Bit {
    type Output = Self;

    fn bitor(self, rhs: Self) -> Self::Output {
        Bit(self.0 | rhs.0)
    }
}

impl BitAnd for Bit {
    type Output = Self;
    fn bitand(self, rhs: Self) -> Self::Output {
        Bit(self.0 & rhs.0)
    }
}

impl BitXor for Bit {
    type Output = Self;
    fn bitxor(self, rhs: Self) -> Self::Output {
        Bit(self.0 ^ rhs.0)
    }
}

impl Not for Bit {
    type Output = Self;
    fn not(self) -> Self::Output {
        Bit(!self.0)
    }
}

impl Zero for Bit {
    fn zero() -> Self {
        Self(false)
    }
    fn set_zero(&mut self) {
        self.0 = false;
    }
    fn is_zero(&self) -> bool {
        !**self
    }
}

impl One for Bit {
    fn one() -> Self {
        Self(true)
    }
    fn set_one(&mut self) {
        self.0 = true;
    }
    fn is_one(&self) -> bool {
        **self
    }
}

impl Pixel for Bit {
    type Subpixel = Self;
    const CHANNEL_COUNT: u8 = 1;
    fn channels(&self) -> &[Self] {
        unimplemented!()
    }
    fn channels_mut(&mut self) -> &mut [Self] {
        unimplemented!()
    }
    const COLOR_MODEL: &'static str = "BLACKANDWHITE";
    fn channels4(&self) -> (Self, Self, Self, Self) {
        (*self, *self, *self, *self)
    }
    fn from_channels(a: Self, b: Self, c: Self, d: Self) -> Self {
        Self(*(a | b | c | d))
    }
    fn from_slice(slice: &[Self]) -> &Self {
        assert_eq!(slice.len(), 1);
        unsafe { &*slice.as_ptr().cast() }
    }
    fn from_slice_mut(slice: &mut [Self]) -> &mut Self {
        assert_eq!(slice.len(), 1);
        unsafe { &mut *slice.as_mut_ptr().cast() }
    }
    fn to_rgb(&self) -> image::Rgb<Bit> {
        image::Rgb([if **self { One::one() } else { Zero::zero() }; 3])
    }
    fn to_rgba(&self) -> image::Rgba<Bit> {
        image::Rgba([if **self { One::one() } else { Zero::zero() }; 4])
    }
    fn to_luma(&self) -> image::Luma<Self> {
        image::Luma([if **self { One::one() } else { Zero::zero() }])
    }
    fn to_luma_alpha(&self) -> image::LumaA<Self> {
        image::LumaA([if **self { One::one() } else { Zero::zero() }; 2])
    }
    fn map<F>(&self, mut f: F) -> Self
    where
        F: FnMut(Self) -> Self,
    {
        Self(*f(*self))
    }
    fn apply<F>(&mut self, mut f: F)
    where
        F: FnMut(Self) -> Self,
    {
        self.0 = *f(*self);
    }
    fn map_with_alpha<F, G>(&self, mut f: F, _: G) -> Self
    where
        F: FnMut(Self) -> Self,
        G: FnMut(Self) -> Self,
    {
        Self(*f(*self))
    }
    fn apply_with_alpha<F, G>(&mut self, f: F, _: G)
    where
        F: FnMut(Self) -> Self,
        G: FnMut(Self) -> Self,
    {
        self.apply(f);
    }
    fn map_without_alpha<F>(&self, mut f: F) -> Self
    where
        F: FnMut(Self) -> Self,
    {
        Self(*f(*self))
    }
    fn apply_without_alpha<F>(&mut self, f: F)
    where
        F: FnMut(Self) -> Self,
    {
        self.apply(f);
    }
    fn map2<F>(&self, other: &Self, mut f: F) -> Self
    where
        F: FnMut(Self, Self) -> Self,
    {
        Self(*f(*self, *other))
    }
    fn apply2<F>(&mut self, other: &Self, mut f: F)
    where
        F: FnMut(Self, Self) -> Self,
    {
        self.0 = *f(*self, *other);
    }
    fn invert(&mut self) {
        self.0 = !self.0;
    }
    fn blend(&mut self, other: &Self) {
        *self -= *other;
    }
}


impl Bounded for Bit {
    fn min_value() -> Self {
        Bit(false)
    }

    fn max_value() -> Self {
        Bit(true)
    }
}

impl Num for Bit {
    type FromStrRadixErr = ParseIntError;

    fn from_str_radix(s: &str, radix: u32) -> Result<Self, Self::FromStrRadixErr> {
        let n = u32::from_str_radix(s, radix)?;
        Ok(Bit(n != 0))
    }
}

impl ToPrimitive for Bit {
    fn to_isize(&self) -> Option<isize> {
        Some(self.0 as isize)
    }

    fn to_i8(&self) -> Option<i8> {
        Some(self.0 as i8)
    }

    fn to_i16(&self) -> Option<i16> {
        Some(self.0 as i16)
    }

    fn to_i32(&self) -> Option<i32> {
        Some(self.0 as i32)
    }

    fn to_i64(&self) -> Option<i64> {
        Some(self.0 as i64)
    }

    fn to_usize(&self) -> Option<usize> {
        Some(self.0 as usize)
    }

    fn to_u8(&self) -> Option<u8> {
        Some(self.0 as u8)
    }

    fn to_u16(&self) -> Option<u16> {
        Some(self.0 as u16)
    }

    fn to_u32(&self) -> Option<u32> {
        Some(self.0 as u32)
    }

    fn to_u64(&self) -> Option<u64> {
        Some(self.0 as u64)
    }

    fn to_f32(&self) -> Option<f32> {
        Some(self.0 as u8 as f32)
    }

    fn to_f64(&self) -> Option<f64> {
        Some(self.0 as u8 as f64)
    }
}

impl NumCast for Bit {
    fn from<T: ToPrimitive>(n: T) -> Option<Self> {
        Some(Bit(n.to_u8()? != 0))
    }
}

impl Primitive for Bit {
    const DEFAULT_MAX_VALUE: Self = Self(true);
    const DEFAULT_MIN_VALUE: Self = Self(false);
}

impl<T: Primitive> From<image::Rgb<T>> for Bit {
    fn from(pixel: image::Rgb<T>) -> Self {
        Self(!pixel.0.iter().all(Zero::is_zero))
    }
}
impl<T: Primitive> From<image::Luma<T>> for Bit {
    fn from(pixel: image::Luma<T>) -> Self {
        Self(!pixel.0[0].is_zero())
    }
}
impl<T: Primitive> From<image::Rgba<T>> for Bit {
    fn from(pixel: image::Rgba<T>) -> Self {
        Self(!pixel.0[3].is_zero())
    }
}
impl<T: Primitive> From<image::LumaA<T>> for Bit {
    fn from(pixel: image::LumaA<T>) -> Self {
        Self(!pixel.0[1].is_zero())
    }
}

impl<T: Primitive> From<&image::Rgb<T>> for Bit {
    fn from(pixel: &image::Rgb<T>) -> Self {
        Self(!pixel.0.iter().all(Zero::is_zero))
    }
}
impl<T: Primitive> From<&image::Luma<T>> for Bit {
    fn from(pixel: &image::Luma<T>) -> Self {
        Self(!pixel.0[0].is_zero())
    }
}
impl<T: Primitive> From<&image::Rgba<T>> for Bit {
    fn from(pixel: &image::Rgba<T>) -> Self {
        Self(!pixel.0[3].is_zero())
    }
}
impl<T: Primitive> From<&image::LumaA<T>> for Bit {
    fn from(pixel: &image::LumaA<T>) -> Self {
        Self(!pixel.0[1].is_zero())
    }
}