feat(domain): implement RelayId newtype with validation
Implement smart constructor that validates relay IDs are within valid range (1-8 for 8-channel relay controller). Add accessor method as_u8() for safe access to inner value. Add comprehensive documentation to satisfy clippy requirements. TDD green phase: Tests from T017 now pass. Ref: T018 (specs/001-modbus-relay-control/tasks.md)
This commit is contained in:
7
backend/src/domain/relay/controler.rs
Normal file
7
backend/src/domain/relay/controler.rs
Normal file
@@ -0,0 +1,7 @@
|
||||
/// Errors that can occur during relay controller operations.
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum ControllerError {
|
||||
/// The provided relay ID is outside the valid range (1-8).
|
||||
#[error("Invalid relay ID: {0}")]
|
||||
InvalidRelayId(u8),
|
||||
}
|
||||
@@ -7,3 +7,5 @@
|
||||
pub mod repository;
|
||||
/// Domain types for relay identification and control.
|
||||
pub mod types;
|
||||
/// Controller error types for relay operations.
|
||||
pub mod controler;
|
||||
|
||||
2
backend/src/domain/relay/types/mod.rs
Normal file
2
backend/src/domain/relay/types/mod.rs
Normal file
@@ -0,0 +1,2 @@
|
||||
mod relayid;
|
||||
pub use relayid::RelayId;
|
||||
@@ -1,3 +1,5 @@
|
||||
use crate::domain::relay::controler::ControllerError;
|
||||
|
||||
/// Unique identifier for a relay in the system.
|
||||
///
|
||||
/// Uses the newtype pattern to provide type safety and prevent mixing relay IDs
|
||||
@@ -7,6 +9,33 @@
|
||||
#[repr(transparent)]
|
||||
pub struct RelayId(u8);
|
||||
|
||||
impl RelayId {
|
||||
/// Creates a new `RelayId` from a relay channel number.
|
||||
///
|
||||
/// This is a smart constructor that validates the relay ID is within the
|
||||
/// valid range (1-8) for an 8-channel relay controller.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Returns `ControllerError::InvalidRelayId` if the ID is not in the range 1-8.
|
||||
pub const fn new(id: u8) -> Result<Self, ControllerError> {
|
||||
if id > 0 && id < 9 {
|
||||
Ok(Self(id))
|
||||
} else {
|
||||
Err(ControllerError::InvalidRelayId(id))
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the inner `u8` value of the relay ID.
|
||||
///
|
||||
/// This accessor method provides access to the underlying relay channel number.
|
||||
#[must_use]
|
||||
pub const fn as_u8(&self) -> u8 {
|
||||
self.0
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
impl std::fmt::Display for RelayId {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
self.0.fmt(f)
|
||||
@@ -211,7 +211,7 @@
|
||||
- **File**: src/domain/relay.rs
|
||||
- **Complexity**: Low | **Uncertainty**: Low
|
||||
|
||||
- [ ] **T018** [US1] [TDD] Implement RelayId newtype with validation
|
||||
- [x] **T018** [US1] [TDD] Implement RelayId newtype with validation
|
||||
- #[repr(transparent)] newtype wrapping u8
|
||||
- Constructor validates 1..=8 range
|
||||
- Implement Display, Debug, Clone, Copy, PartialEq, Eq
|
||||
|
||||
Reference in New Issue
Block a user