use crate::stream_source::RwLockPoisonRecover as _;
use std::sync::RwLock;
#[derive(Debug, Default)]
pub struct StatusCache {
battery_level: RwLock<Option<u8>>,
motion: RwLock<Option<bool>>,
floodlight: RwLock<Option<bool>>,
floodlight_tasks: RwLock<Option<bool>>,
pir: RwLock<Option<bool>>,
}
impl StatusCache {
pub fn set_battery_level(&self, level: u8) {
*self.battery_level.write_recover() = Some(level);
}
pub fn battery_level(&self) -> Option<u8> {
*self.battery_level.read_recover()
}
pub fn set_motion(&self, detected: bool) {
*self.motion.write_recover() = Some(detected);
}
pub fn motion(&self) -> Option<bool> {
*self.motion.read_recover()
}
pub fn set_floodlight(&self, on: bool) {
*self.floodlight.write_recover() = Some(on);
}
pub fn floodlight(&self) -> Option<bool> {
*self.floodlight.read_recover()
}
pub fn set_floodlight_tasks(&self, enabled: bool) {
*self.floodlight_tasks.write_recover() = Some(enabled);
}
pub fn floodlight_tasks(&self) -> Option<bool> {
*self.floodlight_tasks.read_recover()
}
pub fn set_pir(&self, enabled: bool) {
*self.pir.write_recover() = Some(enabled);
}
pub fn pir(&self) -> Option<bool> {
*self.pir.read_recover()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn defaults_to_none() {
let c = StatusCache::default();
assert_eq!(c.battery_level(), None);
assert_eq!(c.motion(), None);
assert_eq!(c.floodlight(), None);
assert_eq!(c.floodlight_tasks(), None);
assert_eq!(c.pir(), None);
}
#[test]
fn round_trips_each_field() {
let c = StatusCache::default();
c.set_battery_level(72);
c.set_motion(true);
c.set_floodlight(false);
c.set_floodlight_tasks(true);
c.set_pir(false);
assert_eq!(c.battery_level(), Some(72));
assert_eq!(c.motion(), Some(true));
assert_eq!(c.floodlight(), Some(false));
assert_eq!(c.floodlight_tasks(), Some(true));
assert_eq!(c.pir(), Some(false));
}
#[test]
fn last_write_wins() {
let c = StatusCache::default();
c.set_battery_level(50);
c.set_battery_level(48);
assert_eq!(c.battery_level(), Some(48));
}
}