oled 0.0.0

OLED driver for embedded-graphics: SSD1357
Documentation
use embedded_graphics_core::{
    pixelcolor::{BinaryColor, Gray4, Rgb888},
    prelude::{GrayColor, PixelColor, RgbColor},
};

/// 5-bit grayscale color.
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Default)]
#[cfg_attr(feature = "defmt", derive(::defmt::Format))]
pub struct Gray5(u8);

impl Gray5 {
    pub const fn new(luma: u8) -> Gray5 {
        Gray5(luma & 0b11111)
    }
}

impl PixelColor for Gray5 {
    type Raw = (); // FIXME: RawUx types are sealed.
}

impl GrayColor for Gray5 {
    fn luma(&self) -> u8 {
        self.0
    }

    const BLACK: Self = Self::new(0);
    const WHITE: Self = Self::new(0b11111);
}

impl From<u8> for Gray5 {
    fn from(other: u8) -> Self {
        Self::new(other)
    }
}

impl From<Gray5> for u8 {
    fn from(other: Gray5) -> Self {
        other.0
    }
}

impl From<Rgb888> for Gray5 {
    fn from(other: Rgb888) -> Self {
        let luma = (other.r() as u16 * 77 + other.g() as u16 * 150 + other.b() as u16 * 29) / 256;
        Self::new((luma >> 3) as u8)
    }
}

impl From<BinaryColor> for Gray5 {
    fn from(other: BinaryColor) -> Self {
        match other {
            BinaryColor::Off => Self::BLACK,
            BinaryColor::On => Self::WHITE,
        }
    }
}

impl From<Gray4> for Gray5 {
    fn from(other: Gray4) -> Self {
        Self::new(convert_channel::<0b1111, 0b11111>(other.luma()))
    }
}

// via embedded-graphics
/// Convert color channel values from one bit depth to another.
///
/// Fixed point implementation of the conversion formula:
/// `out = round(in * from_max / to_max)`
const fn convert_channel<const FROM_MAX: u8, const TO_MAX: u8>(value: u8) -> u8 {
    if TO_MAX != FROM_MAX {
        const SHIFT: usize = 24;
        const CONST_0_5: u32 = 1 << (SHIFT - 1);

        // `value * from_max / to_max` scaled by `1 << SHIFT`.
        let result = value as u32 * (((TO_MAX as u32) << SHIFT) / FROM_MAX as u32);

        // Scale the result back down into an u8.
        ((result + CONST_0_5) >> SHIFT) as u8
    } else {
        value
    }
}