1#![no_std]
32
33#[cfg(feature = "std")]
34extern crate std;
35
36pub mod bus;
37pub mod channel;
38pub mod error;
39pub mod filter;
40pub mod frame;
41pub mod id;
42pub mod timing;
43
44#[cfg(feature = "async")]
45pub mod async_channel;
46
47pub use bus::{BusState, BusStatus, ErrorCounters};
49pub use channel::{Receive, ReceiveFd, Transmit, TransmitFd};
50pub use error::CanError;
51pub use filter::{Filter, Filterable};
52pub use frame::{CanFdFrame, CanFrame, Frame, Timestamped};
53pub use id::CanId;
54pub use timing::SamplePoint;
55
56#[cfg(feature = "async")]
57pub use async_channel::{AsyncReceive, AsyncReceiveFd, AsyncTransmit, AsyncTransmitFd};
58
59#[cfg(all(test, feature = "std"))]
60mod tests {
61 use super::*;
62 use std::collections::VecDeque;
63 use std::fmt;
64 use std::string::String;
65 use std::time::{Duration, Instant};
66 use std::vec::Vec;
67
68 #[derive(Debug)]
71 struct MockError(String);
72
73 impl fmt::Display for MockError {
74 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
75 write!(f, "MockError: {}", self.0)
76 }
77 }
78
79 impl std::error::Error for MockError {}
80
81 struct MockChannel {
84 tx_log: Vec<CanFrame>,
85 rx_queue: VecDeque<CanFrame>,
86 }
87
88 impl MockChannel {
89 const fn new() -> Self {
90 Self {
91 tx_log: Vec::new(),
92 rx_queue: VecDeque::new(),
93 }
94 }
95
96 fn push_rx(&mut self, frame: CanFrame) {
97 self.rx_queue.push_back(frame);
98 }
99 }
100
101 impl Transmit for MockChannel {
102 type Error = MockError;
103
104 fn transmit(&mut self, frame: &CanFrame) -> Result<(), Self::Error> {
105 self.tx_log.push(frame.clone());
106 Ok(())
107 }
108 }
109
110 impl Receive for MockChannel {
111 type Error = MockError;
112 type Timestamp = Instant;
113
114 fn receive(&mut self) -> Result<Timestamped<CanFrame, Instant>, Self::Error> {
115 self.rx_queue
116 .pop_front()
117 .map(|f| Timestamped::new(f, Instant::now()))
118 .ok_or_else(|| MockError("no frames available".into()))
119 }
120
121 fn try_receive(&mut self) -> Result<Option<Timestamped<CanFrame, Instant>>, Self::Error> {
122 Ok(self
123 .rx_queue
124 .pop_front()
125 .map(|f| Timestamped::new(f, Instant::now())))
126 }
127
128 fn receive_timeout(
129 &mut self,
130 _timeout: Duration,
131 ) -> Result<Option<Timestamped<CanFrame, Instant>>, Self::Error> {
132 self.try_receive()
134 }
135 }
136
137 #[test]
140 fn can_id_standard_valid() {
141 let id = CanId::new_standard(0x123).unwrap();
142 assert_eq!(id.raw(), 0x123);
143 assert!(id.is_standard());
144 }
145
146 #[test]
147 fn can_id_standard_max() {
148 assert!(CanId::new_standard(0x7FF).is_some());
149 assert!(CanId::new_standard(0x800).is_none());
150 }
151
152 #[test]
153 fn can_id_extended_valid() {
154 let id = CanId::new_extended(0x1234_5678).unwrap();
155 assert_eq!(id.raw(), 0x1234_5678);
156 assert!(id.is_extended());
157 }
158
159 #[test]
160 fn can_id_extended_max() {
161 assert!(CanId::new_extended(0x1FFF_FFFF).is_some());
162 assert!(CanId::new_extended(0x2000_0000).is_none());
163 }
164
165 #[test]
166 fn can_frame_valid() {
167 let id = CanId::new_standard(0x100).unwrap();
168 let frame = CanFrame::new(id, &[1, 2, 3]).unwrap();
169 assert_eq!(frame.id(), id);
170 assert_eq!(frame.len(), 3);
171 assert_eq!(frame.data(), &[1, 2, 3]);
172 }
173
174 #[test]
175 fn can_frame_empty() {
176 let id = CanId::new_standard(0x000).unwrap();
177 let frame = CanFrame::new(id, &[]).unwrap();
178 assert_eq!(frame.len(), 0);
179 assert_eq!(frame.data(), &[]);
180 }
181
182 #[test]
183 fn can_frame_too_long() {
184 let id = CanId::new_standard(0x100).unwrap();
185 assert!(CanFrame::new(id, &[0; 9]).is_none());
186 }
187
188 #[test]
189 fn can_fd_frame_valid() {
190 let id = CanId::new_extended(0x100).unwrap();
191 let data = [0xAA; 32];
192 let frame = CanFdFrame::new(id, &data, true, false).unwrap();
193 assert_eq!(frame.len(), 32);
194 assert_eq!(frame.data(), &data);
195 assert!(frame.brs());
196 assert!(!frame.esi());
197 }
198
199 #[test]
200 fn can_fd_frame_invalid_dlc() {
201 let id = CanId::new_standard(0x100).unwrap();
202 assert!(CanFdFrame::new(id, &[0; 9], false, false).is_none());
204 }
205
206 #[test]
207 fn frame_enum_accessors() {
208 let id = CanId::new_standard(0x200).unwrap();
209 let classic = CanFrame::new(id, &[0xFF]).unwrap();
210 let frame = Frame::Can(classic);
211 assert_eq!(frame.id(), id);
212 assert_eq!(frame.len(), 1);
213 assert_eq!(frame.data(), &[0xFF]);
214 }
215
216 #[test]
217 fn timestamped_wrapper() {
218 let id = CanId::new_standard(0x100).unwrap();
219 let frame = CanFrame::new(id, &[1, 2]).unwrap();
220 let now = Instant::now();
221 let ts = Timestamped::new(frame.clone(), now);
222 assert_eq!(ts.frame(), &frame);
223 assert_eq!(*ts.timestamp(), now);
224 assert_eq!(ts.into_frame(), frame);
225 }
226
227 #[test]
228 fn mock_transmit_receive() {
229 let mut ch = MockChannel::new();
230 let id = CanId::new_standard(0x100).unwrap();
231 let frame = CanFrame::new(id, &[1, 2]).unwrap();
232
233 ch.transmit(&frame).unwrap();
234 assert_eq!(ch.tx_log.len(), 1);
235 assert_eq!(ch.tx_log[0], frame);
236
237 assert!(ch.try_receive().unwrap().is_none());
239
240 ch.push_rx(frame.clone());
242 let received = ch.receive().unwrap();
243 assert_eq!(received.into_frame(), frame);
244 }
245
246 #[test]
247 fn mock_receive_timeout() {
248 let mut ch = MockChannel::new();
249 let id = CanId::new_standard(0x100).unwrap();
250 let frame = CanFrame::new(id, &[0xAB]).unwrap();
251
252 let result = ch.receive_timeout(Duration::from_millis(100)).unwrap();
254 assert!(result.is_none());
255
256 ch.push_rx(frame.clone());
258 let result = ch.receive_timeout(Duration::from_millis(100)).unwrap();
259 assert_eq!(result.unwrap().into_frame(), frame);
260 }
261
262 fn send_and_recv<T: Transmit<Error = E> + Receive<Error = E>, E: CanError>(
264 channel: &mut T,
265 frame: &CanFrame,
266 ) -> Result<Option<CanFrame>, E> {
267 channel.transmit(frame)?;
268 Ok(channel.try_receive()?.map(Timestamped::into_frame))
269 }
270
271 #[test]
272 fn generic_function_over_traits() {
273 let mut ch = MockChannel::new();
274 let id = CanId::new_standard(0x42).unwrap();
275 let frame = CanFrame::new(id, &[0xBE, 0xEF]).unwrap();
276
277 ch.push_rx(frame.clone());
278 let result = send_and_recv(&mut ch, &frame).unwrap();
279 assert_eq!(result, Some(frame));
280 }
281
282 #[test]
283 fn bus_state_enum() {
284 let state = BusState::ErrorActive;
285 assert_eq!(state, BusState::ErrorActive);
286 assert_ne!(state, BusState::BusOff);
287
288 let counters = ErrorCounters {
289 transmit: 0,
290 receive: 0,
291 };
292 assert_eq!(counters.transmit, 0);
293 }
294}