#[cfg(doc)]
use crate::protocol;
use crate::protocol::wire::PackedSquares;
use crate::protocol::{BOARD_STATE_LENGTH, SQUARE_COUNT, Square};
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
pub enum LedColor {
#[default]
Off,
Red,
Green,
Blue,
}
impl LedColor {
const fn encoded(self) -> u8 {
match self {
Self::Off => 0,
Self::Red => 1,
Self::Green => 2,
Self::Blue => 3,
}
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct LedPattern {
squares: [LedColor; SQUARE_COUNT],
}
impl LedPattern {
pub const fn new(squares: [LedColor; SQUARE_COUNT]) -> Self {
Self { squares }
}
pub const fn all(color: LedColor) -> Self {
Self {
squares: [color; SQUARE_COUNT],
}
}
pub const fn color_at(&self, square: Square) -> LedColor {
self.squares[square.index()]
}
pub fn set_color(&mut self, square: Square, color: LedColor) {
self.squares[square.index()] = color;
}
pub(crate) fn encode(&self) -> [u8; BOARD_STATE_LENGTH] {
PackedSquares::encode(&self.squares, LedColor::encoded).into_bytes()
}
}
impl Default for LedPattern {
fn default() -> Self {
Self::all(LedColor::Off)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::protocol::{File, Rank};
#[test]
fn colors_are_accessed_by_square() {
let square = Square::new(File::C, Rank::Six);
let mut pattern = LedPattern::default();
pattern.set_color(square, LedColor::Blue);
assert_eq!(pattern.color_at(square), LedColor::Blue);
}
}