use scpi::prelude::*; use scpi::Context; use scpi::error::Result; use core::concat; use arrayvec::{ArrayVec, ArrayString}; pub trait MqttScpiTranslator { // Convert an MQTT publish message into SCPI compatible command // The argument part/ MQTT message must follow SCPI standard for parameter formatting fn run_with_mqtt(&mut self, topic: &str, args: &str, response: &mut FMT) -> Result<()>; } impl<'a, T: Device> MqttScpiTranslator for Context<'a, T> { fn run_with_mqtt(&mut self, topic: &str, args: &str, response: &mut FMT) -> Result<()> where FMT: Formatter, { // Create a fixed-size buffer to handle slice operation let mut buffer = ArrayVec::<[u8; 1024]>::new(); // Copy MQTT topic, convert it into SCPI header format for i in topic.chars() { if i == '/' { // The topic separator is colon(':') in SCPI, and slash('/') in MQTT buffer.try_push(b':') .map_err(|_| ErrorCode::OutOfMemory)?; } else { buffer.try_push(i as u8) .map_err(|_| ErrorCode::OutOfMemory)?; } } // Place a space bar between header and parameter buffer.try_push(b' ') .map_err(|_| ErrorCode::OutOfMemory)?; // Copy the arguments into the buffer for i in args.chars() { buffer.try_push(i as u8) .map_err(|_| ErrorCode::OutOfMemory)?; } self.run(buffer.as_slice(), response) } }