use bytes::{Buf, BufMut};
use crate::{SbpMessage, de::CrcError, messages::SbpMsgParseError, wire_format::WireFormat};
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(Debug, Eq, PartialEq, Clone)]
pub struct Invalid {
#[cfg_attr(feature = "serde", serde(default, skip_serializing))]
pub msg_id: Option<u16>,
#[cfg_attr(feature = "serde", serde(default, skip_serializing, alias = "sender"))]
pub sender_id: Option<u16>,
#[cfg_attr(feature = "serde", serde(default, skip_serializing))]
pub crc: Option<u16>,
#[cfg_attr(feature = "serde", serde(default, skip))]
pub invalid_frame: Vec<u8>,
}
impl SbpMessage for Invalid {
fn message_name(&self) -> &'static str {
"INVALID"
}
fn message_type(&self) -> Option<u16> {
self.msg_id
}
fn sender_id(&self) -> Option<u16> {
self.sender_id
}
fn set_sender_id(&mut self, new_id: u16) {
self.sender_id = Some(new_id);
}
fn encoded_len(&self) -> usize {
WireFormat::len(self)
}
fn is_valid(&self) -> bool {
false
}
fn into_valid_msg(self) -> Result<Self, Self> {
Err(self)
}
}
impl WireFormat for Invalid {
fn len(&self) -> usize {
self.invalid_frame.len()
}
fn write<B: BufMut>(&self, buf: &mut B) {
self.invalid_frame.write(buf)
}
fn parse_unchecked<B: Buf>(buf: &mut B) -> Self {
Invalid {
msg_id: None,
sender_id: None,
crc: None,
invalid_frame: WireFormat::parse_unchecked(buf),
}
}
}
impl From<SbpMsgParseError> for Invalid {
fn from(
SbpMsgParseError {
msg_type,
sender_id,
invalid_payload: msg_payload,
}: SbpMsgParseError,
) -> Self {
let mut payload =
Vec::with_capacity(msg_payload.len() + crate::HEADER_LEN + crate::CRC_LEN);
crate::PREAMBLE.write(&mut payload);
msg_type.write(&mut payload);
sender_id.write(&mut payload);
(msg_payload.len() as u8).write(&mut payload);
msg_payload.write(&mut payload);
let crc =
crc16::State::<crc16::XMODEM>::calculate(payload.get(1..).expect("vec has capacity"));
crc.write(&mut payload);
Self {
msg_id: Some(msg_type),
sender_id: Some(sender_id),
invalid_frame: payload,
crc: Some(crc),
}
}
}
impl From<CrcError> for Invalid {
fn from(
CrcError {
msg_type,
sender_id,
invalid_frame,
crc,
}: CrcError,
) -> Self {
Self {
msg_id: msg_type,
sender_id,
invalid_frame,
crc,
}
}
}