use crate::{
controller::{
ComboSpeedRemoteController, DirectRemoteController, ExtendedRemoteController,
SpeedRemoteController,
},
device::{DefaultPulseTransmitter, PulseTransmitter},
Result,
};
use crate::{Channel, Output};
use std::path::Path;
pub struct BrickBeam<T: PulseTransmitter = DefaultPulseTransmitter> {
pulse_transmitter: T,
}
impl BrickBeam<DefaultPulseTransmitter> {
#[cfg(feature = "cir")]
pub fn new(tx_device_path: impl AsRef<Path>) -> Result<Self> {
let pulse_transmitter = crate::device::CirPulseTransmitter::new(tx_device_path)?;
Ok(Self { pulse_transmitter })
}
#[cfg(not(feature = "cir"))]
pub fn new(_tx_device_path: impl AsRef<Path>) -> Result<Self> {
let pulse_transmitter = crate::device::PulseTransmitterEmulator;
Ok(Self { pulse_transmitter })
}
}
impl<T: PulseTransmitter> BrickBeam<T> {
pub fn create_speed_remote_controller(
&self,
channel: Channel,
output: Output,
) -> Result<SpeedRemoteController<T>> {
SpeedRemoteController::new(&self.pulse_transmitter, channel, output)
}
pub fn create_combo_speed_remote_controller(
&self,
channel: Channel,
) -> Result<ComboSpeedRemoteController<T>> {
ComboSpeedRemoteController::new(&self.pulse_transmitter, channel)
}
pub fn create_direct_remote_controller(
&self,
channel: Channel,
) -> Result<DirectRemoteController<T>> {
DirectRemoteController::new(&self.pulse_transmitter, channel)
}
pub fn create_extended_remote_controller(
&self,
channel: Channel,
) -> Result<ExtendedRemoteController<T>> {
ExtendedRemoteController::new(&self.pulse_transmitter, channel)
}
}
#[cfg(test)]
mod tests {
use crate::{Channel, Error, Output, PulseTransmitter, SingleOutputCommand};
use super::BrickBeam;
#[test]
fn test_brick_beam_factory() {
let beam = BrickBeam::new("/dev/lirc0").unwrap();
beam.create_speed_remote_controller(Channel::One, Output::RED)
.unwrap();
beam.create_combo_speed_remote_controller(Channel::Two)
.unwrap();
beam.create_direct_remote_controller(Channel::Three)
.unwrap();
beam.create_extended_remote_controller(Channel::Four)
.unwrap();
}
struct FailingTransmitter;
impl PulseTransmitter for FailingTransmitter {
fn send_pulses(&self, _pulses: &[u32]) -> crate::Result<()> {
Err(Error::Transmitting("Mocked failure".to_string()))
}
}
#[test]
fn test_send_fails() {
let beam = BrickBeam {
pulse_transmitter: FailingTransmitter,
};
let mut motor = beam
.create_speed_remote_controller(Channel::One, Output::RED)
.unwrap();
let result = motor.send(SingleOutputCommand::PWM(5));
assert!(result.is_err());
match result {
Err(Error::Transmitting(msg)) => assert!(msg.contains("Mocked failure")),
_ => panic!("Expected Transmitting error"),
}
}
}