use crate::id::CanId;
const CAN_MAX_LEN: usize = 8;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct CanFrame {
id: CanId,
len: u8,
data: [u8; 8],
}
impl CanFrame {
#[must_use]
pub fn new(id: CanId, data: &[u8]) -> Option<Self> {
if data.len() > CAN_MAX_LEN {
return None;
}
let mut buf = [0u8; 8];
buf[..data.len()].copy_from_slice(data);
Some(CanFrame {
id,
len: data.len() as u8,
data: buf,
})
}
pub fn id(&self) -> CanId {
self.id
}
pub fn len(&self) -> usize {
self.len as usize
}
pub fn is_empty(&self) -> bool {
self.len == 0
}
pub fn data(&self) -> &[u8] {
&self.data[..self.len as usize]
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct CanFdFrame {
id: CanId,
len: u8,
data: [u8; 64],
brs: bool,
esi: bool,
}
impl CanFdFrame {
#[must_use]
pub fn new(id: CanId, data: &[u8], brs: bool, esi: bool) -> Option<Self> {
if !matches!(data.len(), 0..=8 | 12 | 16 | 20 | 24 | 32 | 48 | 64) {
return None;
}
let mut buf = [0u8; 64];
buf[..data.len()].copy_from_slice(data);
Some(CanFdFrame {
id,
len: data.len() as u8,
data: buf,
brs,
esi,
})
}
pub fn id(&self) -> CanId {
self.id
}
pub fn len(&self) -> usize {
self.len as usize
}
pub fn is_empty(&self) -> bool {
self.len == 0
}
pub fn data(&self) -> &[u8] {
&self.data[..self.len as usize]
}
pub fn brs(&self) -> bool {
self.brs
}
pub fn esi(&self) -> bool {
self.esi
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Frame {
Can(CanFrame),
Fd(CanFdFrame),
}
impl Frame {
pub fn id(&self) -> CanId {
match self {
Frame::Can(f) => f.id(),
Frame::Fd(f) => f.id(),
}
}
pub fn data(&self) -> &[u8] {
match self {
Frame::Can(f) => f.data(),
Frame::Fd(f) => f.data(),
}
}
pub fn len(&self) -> usize {
match self {
Frame::Can(f) => f.len(),
Frame::Fd(f) => f.len(),
}
}
pub fn is_empty(&self) -> bool {
match self {
Frame::Can(f) => f.is_empty(),
Frame::Fd(f) => f.is_empty(),
}
}
}
#[derive(Debug, Clone)]
pub struct Timestamped<F, T> {
frame: F,
timestamp: T,
}
impl<F, T> Timestamped<F, T> {
pub fn new(frame: F, timestamp: T) -> Self {
Timestamped { frame, timestamp }
}
pub fn frame(&self) -> &F {
&self.frame
}
pub fn timestamp(&self) -> &T {
&self.timestamp
}
pub fn into_frame(self) -> F {
self.frame
}
}