Skip to main content

can_utils_rs/setup/
models.rs

1use std::fmt;
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq)]
4pub enum CanBitrate {
5    B10K = 10_000,
6    B20K = 20_000,
7    B50K = 50_000,
8    B100K = 100_000,
9    B125K = 125_000,
10    B250K = 250_000,
11    B500K = 500_000,
12    B1M = 1_000_000,
13}
14
15impl fmt::Display for CanBitrate {
16    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
17        let label = match self {
18            CanBitrate::B1M => "1 Mbit".to_string(),
19            CanBitrate::B500K => "500 kbit".to_string(),
20            CanBitrate::B250K => "250 kbit".to_string(),
21            CanBitrate::B125K => "125 kbit".to_string(),
22            CanBitrate::B100K => "100 kbit".to_string(),
23            CanBitrate::B50K => "50 kbit".to_string(),
24            CanBitrate::B20K => "20 kbit".to_string(),
25            CanBitrate::B10K => "10 kbit".to_string(),
26        };
27
28        write!(f, "{} ({})", label, *self as u32)
29    }
30}
31
32impl CanBitrate {
33    pub fn bitrate(&self) -> u32 {
34        *self as u32
35    }
36    pub fn can_bitrates() -> Vec<CanBitrate> {
37        let mut bitrates = vec![
38            CanBitrate::B10K,
39            CanBitrate::B20K,
40            CanBitrate::B50K,
41            CanBitrate::B100K,
42            CanBitrate::B125K,
43            CanBitrate::B250K,
44            CanBitrate::B500K,
45            CanBitrate::B1M,
46        ];
47
48        bitrates.sort_by_key(|b| std::cmp::Reverse(*b as u32));
49        bitrates
50    }
51}
52
53#[derive(Debug, Clone)]
54pub struct SlcanSpeed {
55    pub bitrate: u32,
56    pub flag: &'static str,
57}
58
59impl fmt::Display for SlcanSpeed {
60    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
61        let label = match self.bitrate {
62            1_000_000 => "1 Mbit".to_string(),
63            _ if self.bitrate >= 1_000 => format!("{} kbit", self.bitrate / 1_000),
64            _ => self.bitrate.to_string(),
65        };
66
67        write!(f, "{:<10} ({}, {})", label, self.bitrate, self.flag)
68    }
69}
70
71pub fn slcan_speeds() -> Vec<SlcanSpeed> {
72    let mut speeds = vec![
73        SlcanSpeed {
74            bitrate: 10_000,
75            flag: "s0",
76        },
77        SlcanSpeed {
78            bitrate: 20_000,
79            flag: "s1",
80        },
81        SlcanSpeed {
82            bitrate: 50_000,
83            flag: "s2",
84        },
85        SlcanSpeed {
86            bitrate: 100_000,
87            flag: "s3",
88        },
89        SlcanSpeed {
90            bitrate: 125_000,
91            flag: "s4",
92        },
93        SlcanSpeed {
94            bitrate: 250_000,
95            flag: "s5",
96        },
97        SlcanSpeed {
98            bitrate: 500_000,
99            flag: "s6",
100        },
101        SlcanSpeed {
102            bitrate: 800_000,
103            flag: "s7",
104        },
105        SlcanSpeed {
106            bitrate: 1_000_000,
107            flag: "s8",
108        },
109    ];
110
111    speeds.sort_by_key(|b| std::cmp::Reverse(b.bitrate));
112    speeds
113}
114
115#[derive(Debug, Clone)]
116pub enum CanMode {
117    Native,
118    Slcan,
119    Virtual,
120}
121
122impl fmt::Display for CanMode {
123    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
124        match self {
125            CanMode::Native => write!(f, "Native CAN bus"),
126            CanMode::Slcan => write!(f, "Non-native CAN bus (slcand)"),
127            CanMode::Virtual => write!(f, "Virtual CAN bus (vcan)"),
128        }
129    }
130}
131
132#[derive(Debug, Clone)]
133pub struct NativeConfig {
134    pub iface: String,
135    pub bitrate: CanBitrate,
136}
137
138impl NativeConfig {
139    pub fn new(iface: String, bitrate: CanBitrate) -> Self {
140        Self { iface, bitrate }
141    }
142}
143
144#[derive(Debug, Clone)]
145pub struct SlcanConfig {
146    pub tty: String,
147    pub iface: String,
148    pub speed: SlcanSpeed,
149    pub uart_baud: u32,
150}
151
152impl SlcanConfig {
153    pub fn new(tty: String, iface: String, speed: SlcanSpeed, uart_baud: u32) -> Self {
154        Self {
155            tty,
156            iface,
157            speed,
158            uart_baud,
159        }
160    }
161}
162
163#[derive(Debug, Clone)]
164pub struct VirtualConfig {
165    pub iface: String,
166}
167
168impl VirtualConfig {
169    pub fn new(iface: String) -> Self {
170        Self { iface }
171    }
172}
173
174#[derive(Debug, Clone)]
175pub enum CanConfig {
176    Native(NativeConfig),
177    Slcan(SlcanConfig),
178    Virtual(VirtualConfig),
179}
180
181impl CanConfig {
182    pub fn new(
183        mode: CanMode,
184        iface: String,
185        bitrate: Option<CanBitrate>,
186        slcan_speed: Option<SlcanSpeed>,
187        uart_baud: Option<u32>,
188    ) -> Self {
189        match mode {
190            CanMode::Native => CanConfig::Native(NativeConfig {
191                iface,
192                bitrate: bitrate.expect("Bitrate is required for Native mode"),
193            }),
194            CanMode::Slcan => CanConfig::Slcan(SlcanConfig {
195                tty: "/dev/ttyUSB0".to_string(), // Default value, can be modified later
196                iface,
197                speed: slcan_speed.expect("SLCAN speed is required for Slcan mode"),
198                uart_baud: uart_baud.expect("UART baud rate is required for Slcan mode"),
199            }),
200            CanMode::Virtual => CanConfig::Virtual(VirtualConfig { iface }),
201        }
202    }
203    pub fn iface(&self) -> &str {
204        match self {
205            CanConfig::Native(cfg) => &cfg.iface,
206            CanConfig::Slcan(cfg) => &cfg.iface,
207            CanConfig::Virtual(cfg) => &cfg.iface,
208        }
209    }
210
211    pub fn set_iface(&mut self, new_iface: String) {
212        match self {
213            CanConfig::Native(cfg) => cfg.iface = new_iface,
214            CanConfig::Slcan(cfg) => cfg.iface = new_iface,
215            CanConfig::Virtual(cfg) => cfg.iface = new_iface,
216        }
217    }
218}
219
220#[derive(Debug, Clone, Copy, PartialEq, Eq)]
221pub enum ExistingIfaceAction {
222    Replace,
223    Rename,
224    Skip,
225    Cancel,
226}
227
228#[derive(Debug, Clone, Copy, PartialEq, Eq)]
229pub enum InterfaceResolution {
230    Proceed,
231    SkipSetup,
232}