diff --git a/examples/mqtt_client.rs b/examples/mqtt_client.rs index aa1681c..cc4d1ad 100644 --- a/examples/mqtt_client.rs +++ b/examples/mqtt_client.rs @@ -272,7 +272,11 @@ fn main() -> ! { .poll(|_client, topic, message, _properties| match topic { topic => { info!("On '{:?}', received: {:?}", topic, message); - context.run_with_mqtt(topic.as_bytes(), &mut buf); + // Why is topic a string while message is a slice? + context.run_with_mqtt(topic, + core::str::from_utf8(message).unwrap(), + &mut buf) + .unwrap(); }, }).is_ok(); diff --git a/src/translation.rs b/src/translation.rs index fd75175..33bd63f 100644 --- a/src/translation.rs +++ b/src/translation.rs @@ -2,27 +2,46 @@ use scpi::prelude::*; use scpi::Context; use scpi::error::Result; -use arrayvec::{ArrayVec}; +use core::concat; + +use arrayvec::{ArrayVec, ArrayString}; pub trait MqttScpiTranslator { - fn run_with_mqtt(&mut self, s: &[u8], response: &mut FMT) -> Result<()>; + // 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, s: &[u8], response: &mut FMT) -> Result<()> + fn run_with_mqtt(&mut self, topic: &str, args: &str, response: &mut FMT) -> Result<()> where FMT: Formatter, { - let mut array_vec = ArrayVec::<[u8; 1024]>::new(); - for i in s.into_iter() { - if *i == b'/' { - array_vec.try_push(b'/') + // 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 { - array_vec.try_push(*i) + buffer.try_push(i as u8) .map_err(|_| ErrorCode::OutOfMemory)?; } } - self.run(array_vec.as_slice(), response) + + // 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) } } \ No newline at end of file