dbc_rs/message/
serialize.rs1use super::Message;
2
3#[cfg(feature = "std")]
4impl Message {
5 #[must_use = "return value should be used"]
6 pub fn to_dbc_string(&self) -> std::string::String {
7 format!(
8 "BO_ {} {} : {} {}",
9 self.id(),
10 self.name(),
11 self.dlc(),
12 self.sender()
13 )
14 }
15
16 #[must_use = "return value should be used"]
17 pub fn to_string_full(&self) -> std::string::String {
18 let mut result = std::string::String::with_capacity(200 + (self.signals.len() * 100));
19 result.push_str(&self.to_dbc_string());
20 result.push('\n');
21
22 for signal in self.signals().iter() {
23 result.push_str(&signal.to_dbc_string());
24 result.push('\n');
25 }
26
27 result
28 }
29}
30
31#[cfg(feature = "std")]
32impl core::fmt::Display for Message {
33 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
34 write!(f, "{}", self.to_string_full())
35 }
36}
37
38#[cfg(test)]
39mod tests {
40 use super::*;
41 use crate::{Parser, Signal};
42
43 #[test]
44 fn test_message_to_dbc_string() {
45 let data = b"BO_ 256 EngineData : 8 ECM";
46 let mut parser = Parser::new(data).unwrap();
47 let signals: &[Signal] = &[];
48 let message = Message::parse(&mut parser, signals).unwrap();
49 let dbc_string = message.to_dbc_string();
50 assert_eq!(dbc_string, "BO_ 256 EngineData : 8 ECM");
51 }
52
53 #[test]
54 fn test_message_to_string_full() {
55 let data = b"BO_ 256 EngineData : 8 ECM";
56 let mut parser = Parser::new(data).unwrap();
57
58 let signal1 = Signal::parse(
59 &mut Parser::new(b"SG_ RPM : 0|16@0+ (0.25,0) [0|8000] \"rpm\"").unwrap(),
60 )
61 .unwrap();
62 let signal2 = Signal::parse(
63 &mut Parser::new(b"SG_ Temp : 16|8@0- (1,-40) [-40|215] \"\xC2\xB0C\"").unwrap(),
64 )
65 .unwrap();
66
67 let message = Message::parse(&mut parser, &[signal1, signal2]).unwrap();
68 let dbc_string = message.to_string_full();
69 assert!(dbc_string.contains("BO_ 256 EngineData : 8 ECM"));
70 assert!(dbc_string.contains("SG_ RPM"));
71 assert!(dbc_string.contains("SG_ Temp"));
72 }
73
74 #[test]
75 fn test_message_to_dbc_string_empty_signals() {
76 let data = b"BO_ 256 EngineData : 8 ECM";
77 let mut parser = Parser::new(data).unwrap();
78 let signals: &[Signal] = &[];
79 let message = Message::parse(&mut parser, signals).unwrap();
80
81 let dbc_string = message.to_dbc_string();
82 assert_eq!(dbc_string, "BO_ 256 EngineData : 8 ECM");
83
84 let dbc_string_with_signals = message.to_string_full();
85 assert_eq!(dbc_string_with_signals, "BO_ 256 EngineData : 8 ECM\n");
86 }
87
88 #[test]
89 fn test_message_to_dbc_string_special_characters() {
90 let data = b"BO_ 1234 Test_Message_With_Underscores : 4 Sender_Node";
91 let mut parser = Parser::new(data).unwrap();
92 let signals: &[Signal] = &[];
93 let message = Message::parse(&mut parser, signals).unwrap();
94
95 let dbc_string = message.to_dbc_string();
96 assert_eq!(
97 dbc_string,
98 "BO_ 1234 Test_Message_With_Underscores : 4 Sender_Node"
99 );
100 }
101
102 #[test]
103 fn test_message_to_dbc_string_extended_id() {
104 let data = b"BO_ 536870911 ExtendedID : 8 ECM";
106 let mut parser = Parser::new(data).unwrap();
107 let signals: &[Signal] = &[];
108 let message = Message::parse(&mut parser, signals).unwrap();
109
110 let dbc_string = message.to_dbc_string();
111 assert_eq!(dbc_string, "BO_ 536870911 ExtendedID : 8 ECM");
112 }
113
114 #[test]
115 fn test_message_to_dbc_string_dlc_edge_cases() {
116 let data = b"BO_ 256 MinDLC : 1 ECM";
118 let mut parser = Parser::new(data).unwrap();
119 let signals: &[Signal] = &[];
120 let message = Message::parse(&mut parser, signals).unwrap();
121 assert_eq!(message.to_dbc_string(), "BO_ 256 MinDLC : 1 ECM");
122
123 let data2 = b"BO_ 257 MaxDLC : 64 ECM";
125 let mut parser2 = Parser::new(data2).unwrap();
126 let signals_empty: &[Signal] = &[];
127 let message2 = Message::parse(&mut parser2, signals_empty).unwrap();
128 assert_eq!(message2.to_dbc_string(), "BO_ 257 MaxDLC : 64 ECM");
129 }
130
131 #[test]
132 fn test_message_display_trait() {
133 let data = b"BO_ 256 EngineData : 8 ECM";
134 let mut parser = Parser::new(data).unwrap();
135
136 let signal = Signal::parse(
138 &mut Parser::new(b"SG_ RPM : 0|16@0+ (0.25,0) [0|8000] \"rpm\" *").unwrap(),
139 )
140 .unwrap();
141
142 let message = Message::parse(&mut parser, &[signal]).unwrap();
143
144 let display_str = format!("{}", message);
145 assert!(display_str.contains("BO_ 256 EngineData : 8 ECM"));
146 assert!(display_str.contains("SG_ RPM"));
147 }
148
149 #[test]
150 fn test_message_to_string_full_multiple() {
151 let data = b"BO_ 256 EngineData : 8 ECM";
152 let mut parser = Parser::new(data).unwrap();
153
154 let signal1 = Signal::parse(
156 &mut Parser::new(b"SG_ RPM : 0|16@0+ (0.25,0) [0|8000] \"rpm\" *").unwrap(),
157 )
158 .unwrap();
159
160 let signal2 = Signal::parse(
161 &mut Parser::new(b"SG_ Temp : 16|8@0- (1,-40) [-40|215] \"\xC2\xB0C\" *").unwrap(),
162 )
163 .unwrap();
164
165 let message = Message::parse(&mut parser, &[signal1, signal2]).unwrap();
166
167 let dbc_string = message.to_string_full();
168 assert!(dbc_string.contains("BO_ 256 EngineData : 8 ECM"));
169 assert!(dbc_string.contains("SG_ RPM"));
170 assert!(dbc_string.contains("SG_ Temp"));
171 let lines: Vec<&str> = dbc_string.lines().collect();
173 assert!(lines.len() >= 3); }
175
176 #[test]
177 fn test_message_can_2_0a_dlc_limits() {
178 for dlc in 1..=8 {
181 let data = format!("BO_ 256 EngineData : {} ECM", dlc);
182 let mut parser = Parser::new(data.as_bytes()).unwrap();
183 let signals: &[Signal] = &[];
184 let message = Message::parse(&mut parser, signals).unwrap();
185 assert_eq!(message.dlc(), dlc);
186 }
187 }
188
189 #[test]
190 fn test_message_can_2_0b_dlc_limits() {
191 for dlc in 1..=8 {
194 let data = format!("BO_ 256 EngineData : {} ECM", dlc);
195 let mut parser = Parser::new(data.as_bytes()).unwrap();
196 let signals: &[Signal] = &[];
197 let message = Message::parse(&mut parser, signals).unwrap();
198 assert_eq!(message.dlc(), dlc);
199 }
200 }
201
202 #[test]
203 fn test_message_can_fd_dlc_limits() {
204 for dlc in [1, 8, 12, 16, 20, 24, 32, 48, 64] {
207 let data = format!("BO_ 256 EngineData : {} ECM", dlc);
208 let mut parser = Parser::new(data.as_bytes()).unwrap();
209 let signals: &[Signal] = &[];
210 let message = Message::parse(&mut parser, signals).unwrap();
211 assert_eq!(message.dlc(), dlc);
212 }
213 }
214
215 #[test]
216 fn test_message_signals_iterator_collect() {
217 let data = b"BO_ 256 EngineData : 8 ECM";
218 let mut parser = Parser::new(data).unwrap();
219
220 let signal1 =
221 Signal::parse(&mut Parser::new(b"SG_ Signal1 : 0|8@0+ (1,0) [0|255] \"\"").unwrap())
222 .unwrap();
223 let signal2 =
224 Signal::parse(&mut Parser::new(b"SG_ Signal2 : 8|8@0+ (1,0) [0|255] \"\"").unwrap())
225 .unwrap();
226 let signal3 =
227 Signal::parse(&mut Parser::new(b"SG_ Signal3 : 16|8@0+ (1,0) [0|255] \"\"").unwrap())
228 .unwrap();
229
230 let message = Message::parse(&mut parser, &[signal1, signal2, signal3]).unwrap();
231
232 let names: Vec<&str> = message.signals().iter().map(|s| s.name()).collect();
234 assert_eq!(names, vec!["Signal1", "Signal2", "Signal3"]);
235 }
236}