use embedded_hal::digital::v2::OutputPin;
pub struct Disabled;
pub struct ActiveLow<G>(pub G);
pub struct ActiveHigh<G>(pub G);
pub trait Led {
fn set_on(&mut self);
fn set_off(&mut self);
}
impl Led for Disabled {
fn set_on(&mut self) {}
fn set_off(&mut self) {}
}
impl<G> Led for ActiveHigh<G>
where
G: OutputPin,
{
fn set_on(&mut self) {
if self.0.set_high().is_err() {
panic!("error setting led high");
}
}
fn set_off(&mut self) {
if self.0.set_low().is_err() {
panic!("error setting led low");
}
}
}
impl<G> Led for ActiveLow<G>
where
G: OutputPin,
{
fn set_on(&mut self) {
if self.0.set_low().is_err() {
panic!("error setting led low");
}
}
fn set_off(&mut self) {
if self.0.set_high().is_err() {
panic!("error setting led high");
}
}
}
pub struct Leds<N, C, S, P, K> {
pub num: N,
pub caps: C,
pub scroll: S,
pub compose: P,
pub kana: K,
}
pub type NoLeds = Leds<Disabled, Disabled, Disabled, Disabled, Disabled>;
impl Default for NoLeds {
fn default() -> Self {
Leds {
num: Disabled,
caps: Disabled,
scroll: Disabled,
compose: Disabled,
kana: Disabled,
}
}
}
impl Leds<Disabled, Disabled, Disabled, Disabled, Disabled> {
pub fn new() -> NoLeds {
Self::default()
}
}
impl<N, C, S, P, K> Leds<N, C, S, P, K> {
pub fn caps<T>(self, caps: T) -> Leds<N, T, S, P, K> {
Leds {
num: self.num,
caps,
scroll: self.scroll,
compose: self.compose,
kana: self.kana,
}
}
pub fn num<T>(self, num: T) -> Leds<T, C, S, P, K> {
Leds {
num,
caps: self.caps,
scroll: self.scroll,
compose: self.compose,
kana: self.kana,
}
}
pub fn scroll<T>(self, scroll: T) -> Leds<N, C, T, P, K> {
Leds {
num: self.num,
caps: self.caps,
scroll,
compose: self.compose,
kana: self.kana,
}
}
pub fn compose<T>(self, compose: T) -> Leds<N, C, S, T, K> {
Leds {
num: self.num,
caps: self.caps,
scroll: self.scroll,
compose,
kana: self.kana,
}
}
pub fn kana<T>(self, kana: T) -> Leds<N, C, S, P, T> {
Leds {
num: self.num,
caps: self.caps,
scroll: self.scroll,
compose: self.compose,
kana,
}
}
}
impl<N, C, S, P, K> LedReport for Leds<N, C, S, P, K>
where
C: Led,
N: Led,
S: Led,
P: Led,
K: Led,
{
fn from_report_byte(&mut self, report: u8) {
let leds: &mut [&mut dyn Led] = &mut [
&mut self.num,
&mut self.caps,
&mut self.scroll,
&mut self.compose,
&mut self.kana,
];
for (bit, led) in leds.iter_mut().enumerate() {
if report & (0x01 << bit) != 0 {
led.set_on();
} else {
led.set_off();
}
}
}
}
pub trait LedReport {
fn from_report_byte(&mut self, report: u8);
}