rs_can/
device.rs

1use crate::{
2    error::Error,
3    frame::{Frame, Id},
4};
5use derive_getters::Getters;
6use serde::{Deserialize, Serialize};
7use std::{
8    any::{type_name, Any},
9    collections::HashMap,
10    hash::Hash,
11    sync::Weak,
12};
13
14pub type CanResult<R, E> = Result<R, E>;
15
16#[async_trait::async_trait]
17pub trait Listener<C, F>: Send + Sync
18where
19    F: Frame
20{
21    fn as_any(&self) -> &dyn Any;
22    /// Callback when frame transmit success.
23    async fn on_frame_transmitted(&self, channel: C, id: Id);
24    /// Callback when frames received.
25    async fn on_frame_received(&self, frames: Weak<Vec<F>>);
26}
27
28#[async_trait::async_trait]
29pub trait Device: Send + Sync + TryFrom<DeviceBuilder<Self::Channel>, Error = Error> {
30    type Channel: Hash + Eq + 'static;
31    type Frame: Frame<Channel = Self::Channel>;
32    #[inline]
33    fn is_closed(&self) -> bool {
34        self.opened_channels().is_empty()
35    }
36    /// get all channels that has opened
37    fn opened_channels(&self) -> Vec<Self::Channel>;
38    /// Transmit a CAN or CAN-FD Frame.
39    async fn transmit(&self, msg: Self::Frame, timeout: Option<u32>) -> CanResult<(), Error>;
40    /// Receive CAN and CAN-FD Frames.
41    async fn receive(
42        &self,
43        channel: Self::Channel,
44        timeout: Option<u32>,
45    ) -> CanResult<Vec<Self::Frame>, Error>;
46    /// Close CAN device.
47    fn shutdown(&mut self);
48}
49
50#[derive(Debug, Default, Deserialize, Serialize, Getters)]
51pub struct ChannelConfig {
52    #[getter(copy)]
53    bitrate: u32,
54    #[getter(copy)]
55    dbitrate: Option<u32>,
56    #[getter(copy)]
57    resistance: Option<bool>,
58    #[serde(skip)]
59    others: HashMap<String, Box<dyn Any>>,
60}
61
62impl ChannelConfig {
63    pub fn new(bitrate: u32) -> Self {
64        Self {
65            bitrate,
66            ..Default::default()
67        }
68    }
69
70    pub fn set_data_bitrate(&mut self, bitrate: u32) -> &mut Self {
71        self.dbitrate = Some(bitrate);
72        self
73    }
74
75    pub fn set_resistance(&mut self, resistance: bool) -> &mut Self {
76        self.resistance = Some(resistance);
77        self
78    }
79
80    pub fn add_other(&mut self, name: &str, other: Box<dyn Any>) -> &mut Self {
81        self.others.insert(name.into(), other);
82        self
83    }
84
85    pub fn get_other<T: Clone + 'static>(&self, name: &str) -> Result<Option<T>, Error> {
86        get_other(&self.others, name)
87    }
88}
89
90#[derive(Debug, Default, Getters)]
91pub struct DeviceBuilder<K: Hash + Eq> {
92    #[getter(rename = "channel_configs")]
93    configs: HashMap<K, ChannelConfig>,
94    others: HashMap<String, Box<dyn Any>>,
95}
96unsafe impl<K: Hash + Eq> Sync for DeviceBuilder<K> {}
97unsafe impl<K: Hash + Eq> Send for DeviceBuilder<K> {}
98
99impl<K: Hash + Eq + Default> DeviceBuilder<K> {
100    pub fn new() -> Self {
101        Self::default()
102    }
103
104    pub fn add_config(&mut self, channel: K, cfg: ChannelConfig) -> &mut Self {
105        self.configs.insert(channel.into(), cfg);
106        self
107    }
108
109    pub fn add_other(&mut self, name: &str, cfg: Box<dyn Any>) -> &mut Self {
110        self.others.insert(name.into(), cfg);
111        self
112    }
113
114    pub fn get_other<T: Clone + 'static>(&self, name: &str) -> Result<Option<T>, Error> {
115        get_other(&self.others, name)
116    }
117
118    pub fn build<T: Device<Channel = K>>(self) -> Result<T, Error> {
119        self.try_into()
120    }
121}
122
123#[inline(always)]
124fn get_other<T: Clone + 'static>(
125    others: &HashMap<String, Box<dyn Any>>,
126    name: &str,
127) -> Result<Option<T>, Error> {
128    match others.get(name) {
129        Some(v) => Ok(Some(
130            v.downcast_ref::<T>()
131                .ok_or(Error::OtherError(format!(
132                    "type mismatched for `{}` expected: `{}`",
133                    name,
134                    type_name::<T>()
135                )))?
136                .clone(),
137        )),
138        None => Ok(None),
139    }
140}
141