dbc_rs/signal/
serialize.rs1use super::Signal;
2use crate::Receivers;
3use std::{
4 fmt::{Display, Formatter, Result},
5 string::String,
6};
7
8impl Signal {
9 #[must_use = "return value should be used"]
10 pub fn to_dbc_string(&self) -> String {
11 let mut result = String::with_capacity(100); result.push_str(" SG_ ");
14 result.push_str(self.name());
15 result.push_str(" : ");
16 result.push_str(&self.start_bit().to_string());
17 result.push('|');
18 result.push_str(&self.length().to_string());
19 result.push('@');
20
21 match self.byte_order() {
24 crate::ByteOrder::BigEndian => result.push('0'), crate::ByteOrder::LittleEndian => result.push('1'), }
27
28 if self.is_unsigned() {
30 result.push('+');
31 } else {
32 result.push('-');
33 }
34
35 result.push_str(" (");
37 use core::fmt::Write;
38 write!(result, "{}", self.factor()).unwrap();
39 result.push(',');
40 write!(result, "{}", self.offset()).unwrap();
41 result.push(')');
42
43 result.push_str(" [");
45 write!(result, "{}", self.min()).unwrap();
46 result.push('|');
47 write!(result, "{}", self.max()).unwrap();
48 result.push(']');
49
50 result.push(' ');
52 if let Some(unit) = self.unit() {
53 result.push('"');
54 result.push_str(unit);
55 result.push('"');
56 } else {
57 result.push_str("\"\"");
58 }
59
60 match self.receivers() {
62 Receivers::Broadcast => {
63 result.push(' ');
64 result.push('*');
65 }
66 Receivers::Nodes(nodes) => {
67 if !nodes.is_empty() {
68 result.push(' ');
69 for (i, node) in self.receivers().iter().enumerate() {
70 if i > 0 {
71 result.push(' ');
72 }
73 result.push_str(node);
74 }
75 }
76 }
77 Receivers::None => {
78 }
80 }
81
82 result
83 }
84}
85
86impl Display for Signal {
87 fn fmt(&self, f: &mut Formatter<'_>) -> Result {
88 write!(f, "{}", self.to_dbc_string())
89 }
90}
91
92#[cfg(test)]
93mod tests {
94 use super::*;
95 use crate::Parser;
96
97 #[test]
98 fn test_signal_to_dbc_string_round_trip() {
99 let test_cases = vec![
101 (
102 r#"SG_ RPM : 0|16@0+ (0.25,0) [0|8000] "rpm" *"#,
103 " SG_ RPM : 0|16@0+ (0.25,0) [0|8000] \"rpm\" *",
104 ),
105 (
106 r#"SG_ Temperature : 16|8@1- (1,-40) [-40|215] "°C" TCM BCM"#,
107 " SG_ Temperature : 16|8@1- (1,-40) [-40|215] \"°C\" TCM BCM",
108 ),
109 (
110 r#"SG_ Flag : 24|1@0+ (1,0) [0|1] "" *"#,
111 " SG_ Flag : 24|1@0+ (1,0) [0|1] \"\" *",
112 ),
113 ];
114
115 for (input_line, expected_output) in test_cases {
116 let mut parser = Parser::new(input_line.as_bytes()).unwrap();
118 let signal = Signal::parse(&mut parser).unwrap();
119
120 let dbc_string = signal.to_dbc_string();
122 assert_eq!(dbc_string, expected_output);
123
124 let mut parser2 = Parser::new(dbc_string.as_bytes()).unwrap();
126 parser2.skip_newlines_and_spaces();
128 let signal2 = Signal::parse(&mut parser2).unwrap();
129
130 assert_eq!(signal.name(), signal2.name());
132 assert_eq!(signal.start_bit(), signal2.start_bit());
133 assert_eq!(signal.length(), signal2.length());
134 assert_eq!(signal.byte_order(), signal2.byte_order());
135 assert_eq!(signal.is_unsigned(), signal2.is_unsigned());
136 assert_eq!(signal.factor(), signal2.factor());
137 assert_eq!(signal.offset(), signal2.offset());
138 assert_eq!(signal.min(), signal2.min());
139 assert_eq!(signal.max(), signal2.max());
140 assert_eq!(signal.unit(), signal2.unit());
141 }
142 }
143}