//! Relay entity representing a relay aggregate in the domain model. use super::types::{RelayId, RelayLabel, RelayState}; /// Relay aggregate representing a physical relay device. /// /// Encapsulates the relay's identity, current state, and optional human-readable label. /// This is the primary domain entity for relay control operations. pub struct Relay { id: RelayId, state: RelayState, label: Option, } impl Relay { /// Creates a new relay with the specified ID, state, and optional label. #[must_use] pub const fn new(id: RelayId, state: RelayState, label: Option) -> Self { Self { id, state, label } } /// Toggles the relay state between On and Off. pub const fn toggle(&mut self) { match self.state { RelayState::On => self.turn_off(), RelayState::Off => self.turn_on(), } } /// Sets the relay state to On. pub const fn turn_on(&mut self) { self.state = RelayState::On; } /// Sets the relay state to Off. pub const fn turn_off(&mut self) { self.state = RelayState::Off; } /// Returns the relay's unique identifier. #[must_use] pub const fn id(&self) -> RelayId { self.id } /// Returns the current state of the relay. #[must_use] pub const fn state(&self) -> RelayState { self.state } /// Returns a copy of the relay's label, if present. #[must_use] pub fn label(&self) -> Option { self.label.clone() } } #[cfg(test)] mod tests { use super::*; #[test] fn test_relay_new_creates_relay() { // Test: Relay::new(RelayId(1), RelayState::Off, None) creates relay let relay_id = RelayId::new(1).unwrap(); let relay = Relay::new(relay_id, RelayState::Off, None); assert_eq!(relay.id(), relay_id); assert_eq!(relay.state(), RelayState::Off); assert_eq!(relay.label(), None); } #[test] fn test_relay_toggle_flips_state() { // Test: relay.toggle() flips state let relay_id = RelayId::new(1).unwrap(); let mut relay = Relay::new(relay_id, RelayState::Off, None); // Toggle from Off to On relay.toggle(); assert_eq!(relay.state(), RelayState::On); // Toggle from On to Off relay.toggle(); assert_eq!(relay.state(), RelayState::Off); } #[test] fn test_relay_turn_on_sets_state_to_on() { // Test: relay.turn_on() sets state to On let relay_id = RelayId::new(1).unwrap(); let mut relay = Relay::new(relay_id, RelayState::Off, None); relay.turn_on(); assert_eq!(relay.state(), RelayState::On); // Calling turn_on when already on should keep it on relay.turn_on(); assert_eq!(relay.state(), RelayState::On); } #[test] fn test_relay_turn_off_sets_state_to_off() { // Test: relay.turn_off() sets state to Off let relay_id = RelayId::new(1).unwrap(); let mut relay = Relay::new(relay_id, RelayState::On, None); relay.turn_off(); assert_eq!(relay.state(), RelayState::Off); // Calling turn_off when already off should keep it off relay.turn_off(); assert_eq!(relay.state(), RelayState::Off); } }