humpback-dds/src/translation.rs

48 lines
1.7 KiB
Rust
Raw Normal View History

2020-09-15 12:17:42 +08:00
use scpi::prelude::*;
use scpi::Context;
use scpi::error::Result;
2020-09-15 14:03:59 +08:00
use log::trace;
use arrayvec::{ArrayVec};
2020-09-15 12:17:42 +08:00
pub trait MqttScpiTranslator {
2020-09-15 13:03:54 +08:00
// 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<FMT: Formatter>(&mut self, topic: &str, args: &str, response: &mut FMT) -> Result<()>;
2020-09-15 12:17:42 +08:00
}
impl<'a, T: Device> MqttScpiTranslator for Context<'a, T> {
2020-09-15 13:03:54 +08:00
fn run_with_mqtt<FMT>(&mut self, topic: &str, args: &str, response: &mut FMT) -> Result<()>
2020-09-15 12:17:42 +08:00
where
FMT: Formatter,
{
2020-09-15 13:03:54 +08:00
// 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':')
2020-09-15 14:03:59 +08:00
.map_err(|_| ErrorCode::OutOfMemory)?;
2020-09-15 12:17:42 +08:00
} else {
2020-09-15 13:03:54 +08:00
buffer.try_push(i as u8)
2020-09-15 14:03:59 +08:00
.map_err(|_| ErrorCode::OutOfMemory)?;
2020-09-15 12:17:42 +08:00
}
}
2020-09-15 13:03:54 +08:00
// 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)?;
}
2020-09-15 14:03:59 +08:00
// Pass the message to SCPI processing unit
trace!("Translated MQTT message into SCPI. Translated command: {}",
core::str::from_utf8(buffer.as_slice()).unwrap());
2020-09-15 13:03:54 +08:00
self.run(buffer.as_slice(), response)
2020-09-15 12:17:42 +08:00
}
}