use crate::data_messages::*;
use crate::receive_error::*;
use libc::size_t;
use std::fmt;
use std::mem::size_of;
use std::os::raw::c_char;
#[repr(C)]
#[derive(Clone, Copy)]
pub struct SerialAccessoryMessage {
pub timestamp: u64,
pub char_array: [c_char; DATA_MESSAGE_CHAR_ARRAY_SIZE],
pub number_of_bytes: size_t,
}
impl Default for SerialAccessoryMessage {
fn default() -> Self {
Self {
timestamp: 0,
char_array: [0; DATA_MESSAGE_CHAR_ARRAY_SIZE],
number_of_bytes: 0,
}
}
}
impl SerialAccessoryMessage {
pub fn char_array_as_string(self) -> String {
char_array_to_string(&self.char_array, self.number_of_bytes)
}
}
impl DataMessage for SerialAccessoryMessage {
fn get_ascii_id() -> u8 {
b'S'
}
fn parse_ascii(message: &str) -> Result<Self, ReceiveError> {
match scan_fmt!(message, "{},{d},{[^\n]}\n", char, u64, String) {
Ok((_, timestamp, string)) => {
let (char_array, number_of_bytes) = string_to_char_array(string);
Ok(Self {
timestamp,
char_array,
number_of_bytes,
})
}
Err(_) => Err(ReceiveError::UnableToParseAsciiMessage),
}
}
fn parse_binary(message: &[u8]) -> Result<Self, ReceiveError> {
#[repr(C, packed)]
struct Header {
_id: u8,
timestamp: u64,
}
let min_message_size = size_of::<Header>() + 1;
if message.len() < min_message_size {
return Err(ReceiveError::InvalidBinaryMessageLength);
}
let timestamp = unsafe {
let ref binary_message = *(message.as_ptr() as *const Header);
binary_message.timestamp
};
let (char_array, number_of_bytes) = slice_to_char_array(&message[size_of::<Header>()..(message.len() - 1)]);
Ok(SerialAccessoryMessage {
timestamp,
char_array,
number_of_bytes,
})
}
fn get_csv_file_name(&self) -> &'static str {
"SerialAccessory.csv"
}
fn get_csv_headings(&self) -> &'static str {
"Timestamp (us),String\n"
}
fn to_csv_row(&self) -> String {
format!("{},{}\n", self.timestamp, char_array_to_string(&self.char_array, self.number_of_bytes))
}
}
impl fmt::Display for SerialAccessoryMessage {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
write!(formatter, "{:>8} us \"{}\"", self.timestamp, char_array_to_string(&self.char_array, self.number_of_bytes))
}
}