rs_can/
device.rs

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