zencan_common/
traits.rs

1//! Common traits
2
3use core::time::Duration;
4
5use crate::messages::CanMessage;
6
7/// A trait for accessing a value
8///
9/// E.g. from an AtomicCell
10pub trait LoadStore<T> {
11    /// Read the value
12    fn load(&self) -> T;
13    /// Store a new value to the
14    fn store(&self, value: T);
15}
16
17/// A synchronous can sender
18pub trait CanSender {
19    /// Send a message to the bus
20    fn send(&mut self, msg: CanMessage) -> Result<(), CanMessage>;
21}
22
23/// A synchronous can receiver
24pub trait CanReceiver {
25    /// The error type returned by recv
26    type Error;
27    /// Attempt to read a message from the receiver, and return None immediately if no message is
28    /// available
29    fn try_recv(&mut self) -> Option<CanMessage>;
30    /// A blocking receive with timeout
31    fn recv(&mut self, timeout: Duration) -> Result<CanMessage, Self::Error>;
32}
33
34/// An async CAN sender trait
35pub trait AsyncCanSender: Send {
36    /// Error type returned by sender
37    type Error: CanSendError;
38    /// Send a message to the bus
39    fn send(
40        &mut self,
41        msg: CanMessage,
42    ) -> impl core::future::Future<Output = Result<(), Self::Error>>;
43}
44
45/// A trait for CAN errors which may come from different types of interfaces
46///
47/// On no_std, all the error can do is return the unsent frame. With `std`, it can convert any
48/// underlying errors into a String.
49pub trait CanSendError: core::fmt::Debug {
50    /// Convert the error into the undelivered message
51    fn into_can_message(self) -> CanMessage;
52
53    /// Get a string describing the error
54    #[cfg(feature = "std")]
55    #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
56    fn message(&self) -> String;
57}
58
59/// An async CAN receiver trait
60pub trait AsyncCanReceiver: Send {
61    /// The error type returned by recv
62    type Error: core::fmt::Debug + Send;
63
64    /// Receive available message immediately
65    fn try_recv(&mut self) -> Option<CanMessage>;
66
67    /// A blocking receive
68    fn recv(
69        &mut self,
70    ) -> impl core::future::Future<Output = Result<CanMessage, Self::Error>> + Send;
71
72    /// Remove any pending messages from the receiver
73    fn flush(&mut self) {
74        while self.try_recv().is_some() {}
75    }
76}