1use super::Signal;
2use std::{
3 fmt::{Display, Formatter, Result},
4 string::String,
5};
6
7impl Signal {
8 #[must_use = "return value should be used"]
9 pub fn to_dbc_string(&self) -> String {
10 let mut result = String::with_capacity(100); result.push_str(" SG_ ");
13 result.push_str(self.name());
14 result.push_str(" : ");
15 result.push_str(&self.start_bit().to_string());
16 result.push('|');
17 result.push_str(&self.length().to_string());
18 result.push('@');
19
20 match self.byte_order() {
23 crate::ByteOrder::BigEndian => result.push('0'), crate::ByteOrder::LittleEndian => result.push('1'), }
26
27 if self.is_unsigned() {
29 result.push('+');
30 } else {
31 result.push('-');
32 }
33
34 result.push_str(" (");
36 use core::fmt::Write;
37 write!(result, "{}", self.factor()).unwrap();
38 result.push(',');
39 write!(result, "{}", self.offset()).unwrap();
40 result.push(')');
41
42 result.push_str(" [");
44 write!(result, "{}", self.min()).unwrap();
45 result.push('|');
46 write!(result, "{}", self.max()).unwrap();
47 result.push(']');
48
49 result.push(' ');
51 if let Some(unit) = self.unit() {
52 result.push('"');
53 result.push_str(unit);
54 result.push('"');
55 } else {
56 result.push_str("\"\"");
57 }
58
59 result.push(' ');
61 result.push_str(&self.receivers().to_dbc_string());
62
63 result
64 }
65}
66
67impl Display for Signal {
68 fn fmt(&self, f: &mut Formatter<'_>) -> Result {
69 write!(f, "{}", self.to_dbc_string())
70 }
71}
72
73#[cfg(test)]
74mod tests {
75 use super::*;
76 use crate::Parser;
77
78 #[test]
79 fn test_signal_to_dbc_string_round_trip() {
80 let test_cases = vec![
84 (
85 r#"SG_ RPM : 0|16@0+ (0.25,0) [0|8000] "rpm" *"#,
87 " SG_ RPM : 0|16@0+ (0.25,0) [0|8000] \"rpm\" Vector__XXX",
88 ),
89 (
90 r#"SG_ Temperature : 16|8@1- (1,-40) [-40|215] "°C" TCM BCM"#,
92 " SG_ Temperature : 16|8@1- (1,-40) [-40|215] \"°C\" TCM,BCM",
93 ),
94 (
95 r#"SG_ Flag : 24|1@0+ (1,0) [0|1] "" *"#,
97 " SG_ Flag : 24|1@0+ (1,0) [0|1] \"\" Vector__XXX",
98 ),
99 ];
100
101 for (input_line, expected_output) in test_cases {
102 let mut parser = Parser::new(input_line.as_bytes()).unwrap();
104 let signal = Signal::parse(&mut parser).unwrap();
105
106 let dbc_string = signal.to_dbc_string();
108 assert_eq!(dbc_string, expected_output);
109
110 let mut parser2 = Parser::new(dbc_string.as_bytes()).unwrap();
112 parser2.skip_newlines_and_spaces();
114 let signal2 = Signal::parse(&mut parser2).unwrap();
115
116 assert_eq!(signal.name(), signal2.name());
118 assert_eq!(signal.start_bit(), signal2.start_bit());
119 assert_eq!(signal.length(), signal2.length());
120 assert_eq!(signal.byte_order(), signal2.byte_order());
121 assert_eq!(signal.is_unsigned(), signal2.is_unsigned());
122 assert_eq!(signal.factor(), signal2.factor());
123 assert_eq!(signal.offset(), signal2.offset());
124 assert_eq!(signal.min(), signal2.min());
125 assert_eq!(signal.max(), signal2.max());
126 assert_eq!(signal.unit(), signal2.unit());
127 }
128 }
129}