use crate::constants::{COMMONS_SIZE, ROWS_SIZE};
use crate::errors::ValidationError;
use crate::types::DisplayData;
use crate::types::DisplayDataAddress;
use core::fmt;
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct LedLocation {
pub row: DisplayDataAddress,
pub common: DisplayData,
}
impl fmt::Display for LedLocation {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "LedLocation(row: {}, common: {})", self.row, self.common)
}
}
impl LedLocation {
#[allow(clippy::new_ret_no_self)]
pub fn new(row: u8, common: u8) -> Result<Self, ValidationError> {
if row >= ROWS_SIZE as u8 {
return Err(ValidationError::ValueTooLarge {
name: "row",
value: row,
limit: ROWS_SIZE as u8,
inclusive: false,
});
}
if common >= COMMONS_SIZE as u8 {
return Err(ValidationError::ValueTooLarge {
name: "common",
value: common,
limit: COMMONS_SIZE as u8,
inclusive: false,
});
}
let row = DisplayDataAddress::from_bits_truncate(row);
let common = DisplayData::from_bits_truncate(1 << common);
Ok(LedLocation { row, common })
}
pub fn row_as_index(self) -> usize {
self.row.bits() as usize
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn default() {
let location = LedLocation::default();
assert!(
DisplayDataAddress::ROW_0 == location.row
&& DisplayData::COMMON_NONE == location.common,
"LedLocation default is (0, None)"
);
}
#[test]
fn new() {
let location = LedLocation::new(0, 0).unwrap();
assert!(
DisplayDataAddress::ROW_0 == location.row && DisplayData::COMMON_0 == location.common,
"LedLocation is (0, 0)"
);
let location = LedLocation::new(15, 7).unwrap();
assert!(
DisplayDataAddress::ROW_15 == location.row && DisplayData::COMMON_7 == location.common,
"LedLocation is (15, 7)"
);
}
#[test]
#[should_panic]
fn row_too_large() {
let _ = LedLocation::new(16, 0).unwrap();
}
#[test]
#[should_panic]
fn common_too_large() {
let _ = LedLocation::new(0, 8).unwrap();
}
#[test]
fn row_as_index() {
let location = LedLocation::new(2, 2).unwrap();
assert_eq!(2usize, location.row_as_index());
}
}