use crate::{
device::PulseTransmitter,
protocols::{ComboDirectCommand, ComboDirectProtocol},
Channel, Result,
};
pub struct DirectRemoteController<'a, T: PulseTransmitter> {
channel: Channel,
pulse_transmitter: &'a T,
protocol: ComboDirectProtocol,
}
impl<'a, T: PulseTransmitter> DirectRemoteController<'a, T> {
pub fn new(pulse_transmitter: &'a T, channel: Channel) -> Result<Self> {
let protocol = ComboDirectProtocol::new()?;
Ok(Self {
protocol,
pulse_transmitter,
channel,
})
}
pub fn send(&mut self, cmd: ComboDirectCommand) -> Result<()> {
let pulses = self.protocol.encode_cmd(self.channel, cmd)?;
self.pulse_transmitter.send_pulses(&pulses)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::device::PulseTransmitter;
use crate::protocols::Channel;
use crate::{DirectState, Error, Result};
struct MockTransmitterSuccess;
impl PulseTransmitter for MockTransmitterSuccess {
fn send_pulses(&self, pulses: &[u32]) -> Result<()> {
assert!(!pulses.is_empty());
Ok(())
}
}
struct MockTransmitterFail;
impl PulseTransmitter for MockTransmitterFail {
fn send_pulses(&self, _pulses: &[u32]) -> Result<()> {
Err(Error::Transmitting("Mock failure".to_string()))
}
}
#[test]
fn test_combo_direct_all_states() {
let transmitter = MockTransmitterSuccess;
let mut controller = DirectRemoteController::new(&transmitter, Channel::One)
.expect("Should create DirectRemoteController");
let states = [
DirectState::Float,
DirectState::Forward,
DirectState::Backward,
DirectState::Brake,
];
for &red_state in &states {
for &blue_state in &states {
let cmd = ComboDirectCommand {
red: red_state,
blue: blue_state,
};
let result = controller.send(cmd);
assert!(
result.is_ok(),
"Command failed for red={:?} blue={:?}",
red_state,
blue_state
);
}
}
}
#[test]
fn test_combo_direct_send_fails() {
let transmitter = MockTransmitterFail;
let mut controller = DirectRemoteController::new(&transmitter, Channel::One)
.expect("Should create DirectRemoteController");
let cmd = ComboDirectCommand {
red: DirectState::Forward,
blue: DirectState::Float,
};
let result = controller.send(cmd);
assert!(result.is_err(), "Expected error from failing transmitter");
match result {
Err(Error::Transmitting(msg)) => assert!(msg.contains("Mock failure")),
_ => panic!("Unexpected error variant"),
}
}
}