use crate::api::{self, sensors};
pub trait StatusModifier: Send + Sync {
fn modify(&self, status: &mut api::Status);
}
pub struct StateFromPeopleNowPresent;
impl StatusModifier for StateFromPeopleNowPresent {
fn modify(&self, status: &mut api::Status) {
let people_now_present: Option<u64> = status
.sensors
.as_ref()
.and_then(|sensors: &sensors::Sensors| sensors.people_now_present.first())
.map(|sensor: &sensors::PeopleNowPresentSensor| sensor.value);
if let Some(count) = people_now_present {
let mut state = status.state.clone().unwrap_or_default();
state.open = Some(count > 0);
#[allow(clippy::comparison_chain)]
if count == 1 {
state.message = Some(format!("{} person here right now", count));
} else if count > 1 {
state.message = Some(format!("{} people here right now", count));
}
status.state = Some(state);
}
}
}
#[cfg(test)]
mod tests {
use super::*;
mod state_from_people_now_present {
use super::*;
#[test]
fn no_sensors() {
let mut status = api::Status {
sensors: None,
..api::Status::default()
};
assert_eq!(status.state, None);
StateFromPeopleNowPresent.modify(&mut status);
assert_eq!(status.sensors, None);
assert_eq!(status.state, None);
}
#[test]
fn no_people_present_sensor() {
let mut status = api::Status {
sensors: Some(sensors::Sensors::default()),
..api::Status::default()
};
assert_eq!(status.state, None);
StateFromPeopleNowPresent.modify(&mut status);
assert_eq!(status.state, None);
}
fn make_pnp_sensor(value: u64) -> sensors::PeopleNowPresentSensor {
sensors::PeopleNowPresentSensor {
metadata: Default::default(),
names: None,
value,
}
}
#[test]
fn zero_people_present() {
let mut status = api::Status {
sensors: Some(sensors::Sensors {
people_now_present: vec![make_pnp_sensor(0)],
..sensors::Sensors::default()
}),
state: Some(api::State::default()),
..api::Status::default()
};
status.state.as_mut().unwrap().message = Some("This will remain unchanged.".to_string());
assert_eq!(
status.state.as_ref().unwrap().message,
Some("This will remain unchanged.".to_string())
);
StateFromPeopleNowPresent.modify(&mut status);
assert_eq!(
status.state.unwrap().message,
Some("This will remain unchanged.".to_string())
);
}
#[test]
fn one_person_present() {
let mut status = api::Status {
sensors: Some(sensors::Sensors {
people_now_present: vec![make_pnp_sensor(1)],
..sensors::Sensors::default()
}),
..api::Status::default()
};
assert_eq!(status.state, None);
StateFromPeopleNowPresent.modify(&mut status);
assert_eq!(
status.state.unwrap().message,
Some("1 person here right now".to_string())
);
}
#[test]
fn two_people_present() {
let mut status = api::Status {
sensors: Some(sensors::Sensors {
people_now_present: vec![make_pnp_sensor(2)],
..sensors::Sensors::default()
}),
..api::Status::default()
};
assert_eq!(status.state, None);
StateFromPeopleNowPresent.modify(&mut status);
assert_eq!(
status.state.as_ref().unwrap().message,
Some("2 people here right now".to_string())
);
}
}
}