use crate::{
device::PulseTransmitter,
protocols::{ComboPwmCommand, ComboPwmProtocol},
Channel, Result,
};
pub struct ComboSpeedRemoteController<'a, T: PulseTransmitter> {
channel: Channel,
pulse_transmitter: &'a T,
protocol: ComboPwmProtocol,
}
impl<'a, T: PulseTransmitter> ComboSpeedRemoteController<'a, T> {
pub fn new(pulse_transmitter: &'a T, channel: Channel) -> Result<Self> {
let protocol = ComboPwmProtocol::new()?;
Ok(Self {
protocol,
pulse_transmitter,
channel,
})
}
pub fn send(&mut self, cmd: ComboPwmCommand) -> 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::{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_speed_various_speeds() {
let transmitter = MockTransmitterSuccess;
let mut controller = ComboSpeedRemoteController::new(&transmitter, Channel::One)
.expect("Should create ComboSpeedRemoteController");
let speeds = [-7, -1, 0, 1, 7, 8];
for &red_speed in &speeds {
for &blue_speed in &speeds {
let cmd = ComboPwmCommand {
speed_red: red_speed,
speed_blue: blue_speed,
};
let result = controller.send(cmd);
assert!(
result.is_ok(),
"ComboPwmCommand failed for red={} blue={}",
red_speed,
blue_speed
);
}
}
}
#[test]
fn test_combo_speed_send_fails() {
let transmitter = MockTransmitterFail;
let mut controller = ComboSpeedRemoteController::new(&transmitter, Channel::One)
.expect("Should create ComboSpeedRemoteController");
let cmd = ComboPwmCommand {
speed_red: 5,
speed_blue: -3,
};
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"),
}
}
}