use embedded_io_async::Read;
use crate::{
error::SbusError,
packet::SbusPacket,
parser::{Parser, SBUS_FRAME_LENGTH},
};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct Async {}
impl super::Mode for Async {}
impl super::Sealed for Async {}
impl<R: Read> Parser<R, Async> {
pub fn new(reader: R) -> Self {
Self {
reader,
_mode: Default::default(),
}
}
pub async fn read_frame(&mut self) -> Result<SbusPacket, SbusError> {
let mut buffer = [0u8; SBUS_FRAME_LENGTH];
self.reader
.read_exact(&mut buffer)
.await
.map_err(|_| SbusError::ReadError)?;
SbusPacket::from_array(&buffer)
}
}
pub type SbusParser<R> = Parser<R, Async>;
#[cfg(test)]
mod tests {
use crate::parser::asynch::SbusParser;
use crate::SbusError;
use embedded_io_adapters::tokio_1::FromTokio;
use std::io::Cursor;
const TEST_PACKET: [u8; 25] = [
0x0F, (1024 & 0x07FF) as u8,
(((1024 & 0x07FF) >> 8) | ((1024 & 0x07FF) << 3)) as u8,
(((1024 & 0x07FF) >> 5) | ((1024 & 0x07FF) << 6)) as u8,
((1024 & 0x07FF) >> 2) as u8,
(((1024 & 0x07FF) >> 10) | ((1024 & 0x07FF) << 1)) as u8,
(((1024 & 0x07FF) >> 7) | ((1024 & 0x07FF) << 4)) as u8,
((1024 & 0x07FF) >> 4) as u8,
((1024 & 0x07FF) << 2) as u8,
(((1024 & 0x07FF) >> 8) | ((1024 & 0x07FF) << 5)) as u8,
((1024 & 0x07FF) >> 1) as u8,
(((1024 & 0x07FF) >> 9) | ((1024 & 0x07FF) << 6)) as u8,
((1024 & 0x07FF) >> 3) as u8,
(((1024 & 0x07FF) >> 10) | ((1024 & 0x07FF) << 1)) as u8,
(((1024 & 0x07FF) >> 7) | ((1024 & 0x07FF) << 4)) as u8,
((1024 & 0x07FF) >> 4) as u8,
((1024 & 0x07FF) << 2) as u8,
(((1024 & 0x07FF) >> 8) | ((1024 & 0x07FF) << 5)) as u8,
((1024 & 0x07FF) >> 1) as u8,
(((1024 & 0x07FF) >> 9) | ((1024 & 0x07FF) << 6)) as u8,
((1024 & 0x07FF) >> 3) as u8,
(((1024 & 0x07FF) >> 10) | ((1024 & 0x07FF) << 1)) as u8,
(((1024 & 0x07FF) >> 7) | ((1024 & 0x07FF) << 4)) as u8,
0x00, 0x00, ];
#[tokio::test]
async fn test_valid_sbus_frame_async() {
let data = [
0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ];
let cursor = Cursor::new(data);
let mut parser = SbusParser::new(FromTokio::new(cursor));
let packet = parser.read_frame().await.expect("Should be a valid frame");
assert_eq!(packet.channels[0], 0);
assert_eq!(packet.channels[15], 0);
assert!(!packet.flags.d1);
assert!(!packet.flags.d2);
assert!(!packet.flags.frame_lost);
assert!(!packet.flags.failsafe);
}
#[tokio::test]
async fn test_invalid_footer_async() {
let mut data = TEST_PACKET;
data[24] = 0x50;
let cursor = Cursor::new(data);
let mut parser = SbusParser::new(FromTokio::new(cursor));
let result = parser.read_frame().await;
assert!(matches!(result, Err(SbusError::InvalidFooter(0x50))));
}
#[tokio::test]
async fn test_invalid_header_async() {
let mut data = TEST_PACKET;
data[0] = 0x00;
let cursor = Cursor::new(data);
let mut parser = SbusParser::new(FromTokio::new(cursor));
let result = parser.read_frame().await;
assert!(matches!(result, Err(SbusError::InvalidHeader(0x00))));
}
}