1mod identifier;
2pub use identifier::*;
3
4use crate::utils::can_dlc;
5use std::fmt::{Display, Formatter, Write};
6
7#[repr(C)]
8#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
9pub enum Type {
10 #[default]
11 Can,
12 CanFd,
13 CanXl,
14}
15
16#[repr(C)]
17#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
18pub enum Direct {
19 #[default]
20 Transmit,
21 Receive,
22}
23
24impl Display for Direct {
25 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
26 match self {
27 Self::Transmit => f.write_str("Tx"),
28 Self::Receive => f.write_str("Rx"),
29 }
30 }
31}
32
33pub trait Frame: Send + Sync {
35 type Channel: Display;
36
37 fn new(id: impl Into<Id>, data: &[u8]) -> Option<Self>
38 where
39 Self: Sized;
40
41 fn new_remote(id: impl Into<Id>, len: usize) -> Option<Self>
42 where
43 Self: Sized;
44
45 fn timestamp(&self) -> u64;
46
47 fn set_timestamp(&mut self, value: Option<u64>) -> &mut Self
48 where
49 Self: Sized;
50
51 fn id(&self) -> Id;
53
54 fn can_type(&self) -> Type;
55
56 fn set_can_type(&mut self, r#type: Type) -> &mut Self
57 where
58 Self: Sized;
59
60 fn is_remote(&self) -> bool;
61
62 fn is_extended(&self) -> bool;
63
64 fn direct(&self) -> Direct;
65
66 fn set_direct(&mut self, direct: Direct) -> &mut Self
67 where
68 Self: Sized;
69
70 fn is_bitrate_switch(&self) -> bool;
71
72 fn set_bitrate_switch(&mut self, value: bool) -> &mut Self
73 where
74 Self: Sized;
75
76 fn is_error_frame(&self) -> bool;
77
78 fn set_error_frame(&mut self, value: bool) -> &mut Self
79 where
80 Self: Sized;
81
82 fn is_esi(&self) -> bool;
84
85 fn set_esi(&mut self, value: bool) -> &mut Self
87 where
88 Self: Sized;
89
90 fn channel(&self) -> Self::Channel;
91
92 fn set_channel(&mut self, value: Self::Channel) -> &mut Self
93 where
94 Self: Sized;
95
96 fn data(&self) -> &[u8];
98
99 fn dlc(&self) -> isize {
100 can_dlc(self.length(), self.can_type())
101 }
102
103 fn length(&self) -> usize;
104}
105
106impl<T: Display> Display for dyn Frame<Channel = T> {
107 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
109 let data_str = if self.is_remote() {
110 " ".to_owned()
111 } else {
112 self.data().iter().fold(String::new(), |mut out, &b| {
113 let _ = write!(out, "{b:02x} ");
114 out
115 })
116 };
117
118 match self.can_type() {
119 Type::Can => {
120 write!(
121 f,
122 "{:.3} {} {}{: <4} {} {} {} {}",
123 self.timestamp() as f64 / 1000.,
124 self.channel(),
125 format!("{: >8x}", self.id().into_bits()),
126 if self.is_extended() { "x" } else { "" },
127 self.direct(),
128 if self.is_remote() { "r" } else { "d" },
130 format!("{: >2}", self.length()),
131 data_str,
132 )
133 }
134 Type::CanFd => {
135 let mut flags = 1 << 12;
136 write!(
137 f,
138 "{:.3} CANFD {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}",
139 self.timestamp() as f64 / 1000.,
140 self.channel(),
141 self.direct(),
142 format!("{: >8x}", self.id().into_bits()),
144 if self.is_bitrate_switch() {
145 flags |= 1 << 13;
146 1
147 } else {
148 0
149 },
150 if self.is_esi() {
151 flags |= 1 << 14;
152 1
153 } else {
154 0
155 },
156 format!("{: >2}", self.dlc()),
157 format!("{: >2}", self.length()),
158 data_str,
159 format!("{: >8}", 0), format!("{: <4}", 0), format!("{: >8x}", flags),
162 format!("{: >8}", 0), format!("{: >8}", 0), format!("{: >8}", 0), format!("{: >8}", 0), format!("{: >8}", 0), )
168 }
169 Type::CanXl => {
170 write!(f, "CANXL Frame")
172 }
173 }
174 }
175}