1use std::collections::VecDeque;
2use log::{info, trace};
3use ftswarm_proto::command::direct::FtSwarmDirectCommand;
4use ftswarm_proto::command::FtSwarmCommand;
5use ftswarm_proto::command::rpc::{FtSwarmRPCCommand, RpcFunction};
6use ftswarm_proto::Deserialized;
7use ftswarm_serial::{SerialError, SwarmSerialPort};
8
9pub struct EmulatedSerialPort(VecDeque<String>);
10
11impl Default for EmulatedSerialPort {
12 fn default() -> Self {
13 Self::new()
14 }
15}
16
17impl EmulatedSerialPort {
18 pub fn new() -> EmulatedSerialPort {
19 EmulatedSerialPort(VecDeque::new())
20 }
21
22 fn handle_direct_command(&mut self, command: FtSwarmDirectCommand) {
23 match command {
24 FtSwarmDirectCommand::Help => { self.0.push_back("Help".to_string()); }
25 FtSwarmDirectCommand::Setup => { self.0.push_back("Setup".to_string()); }
26 FtSwarmDirectCommand::Halt => {}
27 FtSwarmDirectCommand::Whoami => {self.0.push_back("ftSwarm100/kelda".to_string()); }
28 FtSwarmDirectCommand::Uptime => { self.0.push_back("uptime: 31.000 s".to_string()); }
29 FtSwarmDirectCommand::StartCli => {}
30 }
31 }
32
33 fn handle_rpc_command(&mut self, command: FtSwarmRPCCommand) {
34 let functions_to_ok = [RpcFunction::Show,
35 RpcFunction::TriggerUserEvent,
36 RpcFunction::SetMicroStepMode,
37 RpcFunction::SetSensorType,
38 RpcFunction::OnTrigger,
39 RpcFunction::SetActorType,
40 RpcFunction::SetSpeed,
41 RpcFunction::SetMotionType,
42 RpcFunction::SetPosition,
43 RpcFunction::SetOffset,
44 RpcFunction::SetColor,
45 RpcFunction::SetBrightness,
46 RpcFunction::SetRegister];
47
48 std::thread::sleep(std::time::Duration::from_millis(10));
49 match command.function {
50 RpcFunction::Subscribe => {}
51 _ => {
52 if functions_to_ok.contains(&command.function) {
53 self.0.push_back("R: Ok".to_string());
54 trace!("Emulator responded with Ok");
55 } else {
56 self.0.push_back("R: 0".to_string());
57 trace!("Emulator responded with 0");
58 }
59 }
60 }
61 }
62}
63
64impl SwarmSerialPort for EmulatedSerialPort {
65 fn available(&self) -> Result<bool, SerialError> {
66 Ok(!self.0.is_empty())
67 }
68
69 fn read_line(&mut self) -> Result<String, SerialError> {
70 self.0.pop_front().ok_or(SerialError::Timeout)
71 }
72
73 fn write_line(&mut self, line: String) -> Result<(), SerialError> {
74 let command = FtSwarmCommand::deserialize(&line).map_err(|_| SerialError::EncodingError)?;
75 match command {
76 FtSwarmCommand::RPC(command) => {
77 info!("Emulator received RPC command: {:?}", command);
78 self.handle_rpc_command(command);
79 }
80 FtSwarmCommand::Direct(command) => {
81 info!("Emulator received direct command: {:?}", command);
82 self.handle_direct_command(command);
83 }
84 }
85 Ok(())
86 }
87
88 fn block_until(&mut self, _: String) -> Result<(), SerialError> {
89 info!("Emulator has started");
90 Ok(())
91 }
92}
93
94#[cfg(test)]
95mod tests;