1use std::{any::{Any, type_name}, 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 fn on_frame_transmitting(&self, channel: C, frame: &F);
16 fn on_frame_transmitted(&self, channel: C, id: Id);
18 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 fn opened_channels(&self) -> Vec<Self::Channel>;
31 fn transmit(&self, msg: Self::Frame, timeout: Option<u32>) -> CanResult<(), Error>;
33 fn receive(&self, channel: Self::Channel, timeout: Option<u32>) -> CanResult<Vec<Self::Frame>, Error>;
35 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 #[getter(rename = "channel_configs")]
82 configs: HashMap<String, ChannelConfig>,
83 others: HashMap<String, Box<dyn Any>>,
84}
85
86impl DeviceBuilder {
87 pub fn new() -> Self {
88 Self::default()
89 }
90
91 pub fn add_config<S: Into<String>>(&mut self, channel: S, cfg: ChannelConfig) -> &mut Self {
92 self.configs.insert(channel.into(), cfg);
93 self
94 }
95
96 pub fn add_other(&mut self, name: &str, cfg: Box<dyn Any>) -> &mut Self {
97 self.others.insert(name.into(), cfg);
98 self
99 }
100
101 pub fn get_other<T: Clone + 'static>(&self, name: &str) -> Result<Option<T>, Error> {
102 get_other(&self.others, name)
103 }
104
105 pub fn build<T: Device>(self) -> Result<T, Error> {
106 self.try_into()
107 }
108}
109
110#[inline(always)]
111fn get_other<T: Clone + 'static>(
112 others: &HashMap<String, Box<dyn Any>>,
113 name: &str
114) -> Result<Option<T>, Error> {
115 match others.get(name) {
116 Some(v) => Ok(Some(
117 v.downcast_ref::<T>()
118 .ok_or(Error::OtherError(
119 format!("type mismatched for `{}` expected: `{}`", name, type_name::<T>())
120 ))?
121 .clone()
122 )),
123 None => Ok(None),
124 }
125}