1pub mod ldf_comment;
2pub mod ldf_diagnostic_frames;
3pub mod ldf_diagnostic_signals;
4pub mod ldf_frames;
5pub mod ldf_header;
6pub mod ldf_node_attributes;
7pub mod ldf_nodes;
8pub mod ldf_schedule_tables;
9pub mod ldf_signal_encoding_types;
10pub mod ldf_signal_representation;
11pub mod ldf_signals;
12
13use crate::ldf::ldf_comment::skip_whitespace;
14use crate::ldf::ldf_diagnostic_frames::{parse_ldf_diagnostic_frames, LdfDiagnosticFrame};
15use crate::ldf::ldf_diagnostic_signals::{parse_ldf_diagnostic_signals, LdfDiagnosticSignal};
16use crate::ldf::ldf_frames::{parse_ldf_frames, LdfFrame};
17use crate::ldf::ldf_header::{parse_ldf_header, LdfHeader};
18use crate::ldf::ldf_node_attributes::{parse_ldf_node_attributes, LdfNodeAttributes};
19use crate::ldf::ldf_nodes::{parse_ldf_nodes, LdfNodes};
20use crate::ldf::ldf_schedule_tables::{parse_ldf_schedule_tables, LdfScheduleTable};
21use crate::ldf::ldf_signal_encoding_types::{parse_ldf_signal_encoding_types, LdfSignalEncodingType};
22use crate::ldf::ldf_signal_representation::{parse_ldf_signal_representation, LdfSignalRepresentation};
23use crate::ldf::ldf_signals::{parse_ldf_signals, LdfSignal};
24
25#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
26pub struct LinLdf {
27 pub header: LdfHeader,
28 pub nodes: LdfNodes,
29 pub signals: Vec<LdfSignal>,
30 pub diagnostic_signals: Vec<LdfDiagnosticSignal>,
31 pub frames: Vec<LdfFrame>,
32 pub diagnostic_frames: Vec<LdfDiagnosticFrame>,
33 pub node_attributes: Vec<LdfNodeAttributes>,
34 pub schedule_tables: Vec<LdfScheduleTable>,
35 pub signal_encoding_types: Vec<LdfSignalEncodingType>,
36 pub signal_representations: Vec<LdfSignalRepresentation>,
37}
38
39impl LinLdf {
40 pub fn parse(s: &str) -> Result<LinLdf, &'static str> {
62 let (s, _) = skip_whitespace(s).map_err(|e| {
64 eprintln!("Failed to skip whitespace and comments: {}", e.to_string());
65 "Failed to skip whitespace and comments"
66 })?;
67 let (s, header) = parse_ldf_header(s).map_err(|e| {
68 eprintln!("Failed to parse header: {}", e);
69 "Failed to parse header"
70 })?;
71
72 let (s, _) = skip_whitespace(s).map_err(|e| {
74 eprintln!("Failed to skip whitespace and comments: {}", e);
75 "Failed to skip whitespace and comments"
76 })?;
77 let (s, nodes) = parse_ldf_nodes(s).map_err(|e| {
78 eprintln!("Failed to parse Nodes section: {}", e);
79 "Failed to parse Nodes section"
80 })?;
81
82 let (s, _) = skip_whitespace(s).map_err(|e| {
84 eprintln!("Failed to skip whitespace and comments: {}", e);
85 "Failed to skip whitespace and comments"
86 })?;
87 let (s, signals) = parse_ldf_signals(s).map_err(|e| {
88 eprintln!("Failed to parse Signals section: {}", e);
89 "Failed to parse Signals section"
90 })?;
91
92 let (s, _) = skip_whitespace(s).map_err(|e| {
94 eprintln!("Failed to skip whitespace and comments: {}", e);
95 "Failed to skip whitespace and comments"
96 })?;
97 let (s, diagnostic_signals) = parse_ldf_diagnostic_signals(s).map_err(|e| {
98 eprintln!("Failed to parse Diagnostic_signals section: {}", e);
99 "Failed to parse Diagnostic_signals section"
100 })?;
101
102 let (s, _) = skip_whitespace(s).map_err(|e| {
104 eprintln!("Failed to skip whitespace and comments: {}", e);
105 "Failed to skip whitespace and comments"
106 })?;
107 let (s, frames) = parse_ldf_frames(s).map_err(|e| {
108 eprintln!("Failed to parse Frames section: {}", e);
109 "Failed to parse Frames section"
110 })?;
111
112 let (s, _) = skip_whitespace(s).map_err(|e| {
114 eprintln!("Failed to skip whitespace and comments: {}", e);
115 "Failed to skip whitespace and comments"
116 })?;
117 let (s, diagnostic_frames) = parse_ldf_diagnostic_frames(s).map_err(|e| {
118 eprintln!("Failed to parse Diagnostic_frames section: {}", e);
119 "Failed to parse Diagnostic_frames section"
120 })?;
121
122 let (s, _) = skip_whitespace(s).map_err(|e| {
124 eprintln!("Failed to skip whitespace and comments: {}", e);
125 "Failed to skip whitespace and comments"
126 })?;
127 let (s, node_attributes) = parse_ldf_node_attributes(s).map_err(|e| {
128 eprintln!("Failed to parse Node_attributes section: {}", e);
129 "Failed to parse Node_attributes section"
130 })?;
131
132 let (s, _) = skip_whitespace(s).map_err(|e| {
134 eprintln!("Failed to skip whitespace and comments: {}", e);
135 "Failed to skip whitespace and comments"
136 })?;
137 let (s, schedule_tables) = parse_ldf_schedule_tables(s).map_err(|e| {
138 eprintln!("Failed to parse Schedule_tables section: {}", e);
139 "Failed to parse Schedule_tables section"
140 })?;
141
142 let (s, _) = skip_whitespace(s).map_err(|e| {
144 eprintln!("Failed to skip whitespace and comments: {}", e);
145 "Failed to skip whitespace and comments"
146 })?;
147 let (s, signal_encoding_types) = parse_ldf_signal_encoding_types(s).map_err(|e| {
148 eprintln!("Failed to parse Signal_encoding_types section: {}", e);
149 "Failed to parse Signal_encoding_types section"
150 })?;
151
152 let (s, _) = skip_whitespace(s).map_err(|e| {
154 eprintln!("Failed to skip whitespace and comments: {}", e);
155 "Failed to skip whitespace and comments"
156 })?;
157 let (_, signal_representations) = parse_ldf_signal_representation(s).map_err(|e| {
158 eprintln!("Failed to parse Signal_representation section: {}", e);
159 "Failed to parse Signal_representation section"
160 })?;
161
162 Ok(LinLdf {
163 header,
164 nodes,
165 signals,
166 diagnostic_signals,
167 frames,
168 diagnostic_frames,
169 node_attributes,
170 schedule_tables,
171 signal_encoding_types,
172 signal_representations,
173 })
174 }
175}
176
177#[cfg(test)]
178mod tests {
179 use crate::ldf::ldf_signals::LdfSignalInitValue;
180
181 use super::*;
182
183 #[test]
184 fn test_parse() {
185 let input = r#"
186 /* MY BLOCK COMMENT */
187
188 LIN_description_file ;
189 LIN_protocol_version = "2.1" ;
190 LIN_language_version = "2.1" ;
191 LIN_speed = 19.2 kbps ;
192
193 Nodes {
194 Master: Master, 5 ms, 0.1 ms ;
195 Slaves: Slave1, Slave2, Slave3 ;
196 }
197
198 // MY LINE COMMENT
199
200 Signals {
201 Signal1: 10, 0, Master, Slave1 , Slave2 ;
202 Signal2: 10, 0, Master, Slave1 ;
203 Signal3: 10, 0, Master, Slave1 ;
204 Signal4: 10, 0, Slave1, Master ;
205 Signal5: 2, 0, Slave1, Master ;
206 Signal6: 1, 0, Slave1, Master ;
207 }
208
209 Diagnostic_signals {
210 MasterReqB0: 8, 0 ; /* MID SECTION COMMENT */
211 MasterReqB1: 8, 0 ;
212 MasterReqB2: 8, 0 ;
213 MasterReqB3: 8, 0 ;
214 MasterReqB4: 8, 0 ;
215 MasterReqB5: 8, 0 ; /* MID SECTION COMMENT */
216 }
217
218 Frames {
219 Frame1: 0, Master, 8 {
220 Signal1, 0 ; /* MID SECTION COMMENT */
221 Signal2, 10 ;
222 }
223 Frame2: 0x16, Slave1, 8 {
224 Signal3, 0 ;
225 Signal4, 10 ;
226 }
227 }
228
229 Diagnostic_frames {
230 MasterReq: 0x3C {
231 MasterReqB0, 0 ;
232 MasterReqB1, 8 ;
233 MasterReqB2, 16 ;
234 MasterReqB3, 24 ;
235 MasterReqB4, 32 ;
236 MasterReqB5, 40 ;
237 MasterReqB6, 48 ;
238 MasterReqB7, 56 ;
239 }
240 SlaveResp: 0x3D {
241 SlaveRespB0, 0 ;
242 SlaveRespB1, 8 ;
243 SlaveRespB2, 16 ;
244 SlaveRespB3, 24 ;
245 SlaveRespB4, 32 ;
246 SlaveRespB5, 40 ;
247 SlaveRespB6, 48 ;
248 SlaveRespB7, 56 ;
249 }
250 }
251
252 Node_attributes {
253 Slave1{
254 LIN_protocol = "2.1" ;
255 configured_NAD = 0xB ;
256 initial_NAD = 0xB ;
257 product_id = 0x123, 0x4567, 8 ;
258 response_error = Signal1 ;
259 P2_min = 100 ms ;
260 ST_min = 0 ms ;
261 N_As_timeout = 1000 ms ;
262 N_Cr_timeout = 1000 ms ;
263 configurable_frames {
264 Frame1 ;
265 Frame2 ;
266 }
267 }
268 Slave2{
269 LIN_protocol = "2.1" ;
270 configured_NAD = 0xC ;
271 initial_NAD = 0xC ;
272 product_id = 0x124, 0x4568, 0x66 ;
273 response_error = Signal2 ;
274 P2_min = 100 ms ;
275 ST_min = 0 ms ;
276 N_As_timeout = 1000 ms ;
277 N_Cr_timeout = 1000 ms ;
278 configurable_frames {
279 Frame1 ;
280 Frame2 ;
281 }
282 }
283 }
284
285 Schedule_tables {
286 AllFrames {
287 Frame1 delay 10 ms ;
288 Frame2 delay 10 ms ;
289 }
290 }
291
292 Signal_encoding_types {
293 ENC_BOOL {
294 logical_value, 0, "FALSE" ;
295 logical_value, 1, "TRUE" ;
296 }
297 ENC_TEMP {
298 physical_value, 0, 1023, 0.2, -40, "degC" ;
299 }
300 ENC_RPM {
301 physical_value, 0, 1023, 10, 0, "rpm" ;
302 }
303 }
304
305 Signal_representation {
306 ENC_BOOL: Signal1, Signal2 ;
307 ENC_TEMP: Signal3, Signal4 ;
308 ENC_RPM: Signal5, Signal6 ;
309 }
310 "#;
311
312 let ldf = LinLdf::parse(input).unwrap();
313
314 assert_eq!(ldf.header.lin_protocol_version, "2.1");
316 assert_eq!(ldf.header.lin_language_version, "2.1");
317 assert_eq!(ldf.header.lin_speed, 19200);
318
319 assert_eq!(ldf.nodes.master.name, "Master");
321 assert_eq!(ldf.nodes.master.time_base, "5 ms");
322 assert_eq!(ldf.nodes.master.jitter, "0.1 ms");
323 assert_eq!(ldf.nodes.slaves.len(), 3);
324 assert_eq!(ldf.nodes.slaves[0].name, "Slave1");
325 assert_eq!(ldf.nodes.slaves[1].name, "Slave2");
326 assert_eq!(ldf.nodes.slaves[2].name, "Slave3");
327
328 assert_eq!(ldf.signals.len(), 6);
330 assert_eq!(ldf.signals[0].name, "Signal1");
331 assert_eq!(ldf.signals[0].signal_size, 10);
332 assert_eq!(ldf.signals[0].init_value, LdfSignalInitValue::Scalar(0));
333 assert_eq!(ldf.signals[0].published_by, "Master");
334 assert_eq!(ldf.signals[0].subscribed_by[0], "Slave1");
335 assert_eq!(ldf.signals[5].name, "Signal6");
336 assert_eq!(ldf.signals[5].signal_size, 1);
337 assert_eq!(ldf.signals[5].init_value, LdfSignalInitValue::Scalar(0));
338 assert_eq!(ldf.signals[5].published_by, "Slave1");
339 assert_eq!(ldf.signals[5].subscribed_by[0], "Master");
340
341 assert_eq!(ldf.diagnostic_signals.len(), 6);
343 assert_eq!(ldf.diagnostic_signals[0].name, "MasterReqB0");
344 assert_eq!(ldf.diagnostic_signals[0].length, 8);
345 assert_eq!(ldf.diagnostic_signals[0].init_value, 0);
346 assert_eq!(ldf.diagnostic_signals[5].name, "MasterReqB5");
347 assert_eq!(ldf.diagnostic_signals[5].length, 8);
348 assert_eq!(ldf.diagnostic_signals[5].init_value, 0);
349
350 assert_eq!(ldf.frames.len(), 2);
352 assert_eq!(ldf.frames[0].frame_name, "Frame1");
353 assert_eq!(ldf.frames[0].frame_id, 0);
354 assert_eq!(ldf.frames[0].published_by, "Master");
355 assert_eq!(ldf.frames[0].frame_size, 8);
356 assert_eq!(ldf.frames[0].signals.len(), 2);
357 assert_eq!(ldf.frames[0].signals[0].signal_name, "Signal1");
358 assert_eq!(ldf.frames[0].signals[0].start_bit, 0);
359 assert_eq!(ldf.frames[0].signals[1].signal_name, "Signal2");
360 assert_eq!(ldf.frames[0].signals[1].start_bit, 10);
361 assert_eq!(ldf.frames[1].frame_name, "Frame2");
362 assert_eq!(ldf.frames[1].frame_id, 0x16);
363 assert_eq!(ldf.frames[1].published_by, "Slave1");
364 assert_eq!(ldf.frames[1].frame_size, 8);
365 assert_eq!(ldf.frames[1].signals.len(), 2);
366 assert_eq!(ldf.frames[1].signals[0].signal_name, "Signal3");
367 assert_eq!(ldf.frames[1].signals[0].start_bit, 0);
368 assert_eq!(ldf.frames[1].signals[1].signal_name, "Signal4");
369 assert_eq!(ldf.frames[1].signals[1].start_bit, 10);
370
371 assert_eq!(ldf.diagnostic_frames.len(), 2);
373 assert_eq!(ldf.diagnostic_frames[0].frame_name, "MasterReq");
374 assert_eq!(ldf.diagnostic_frames[0].frame_id, 0x3C);
375 assert_eq!(ldf.diagnostic_frames[0].signals.len(), 8);
376 assert_eq!(ldf.diagnostic_frames[0].signals[0].signal_name, "MasterReqB0");
377 assert_eq!(ldf.diagnostic_frames[0].signals[0].start_bit, 0);
378 assert_eq!(ldf.diagnostic_frames[0].signals[7].signal_name, "MasterReqB7");
379 assert_eq!(ldf.diagnostic_frames[0].signals[7].start_bit, 56);
380 assert_eq!(ldf.diagnostic_frames[1].frame_name, "SlaveResp");
381 assert_eq!(ldf.diagnostic_frames[1].frame_id, 0x3D);
382 assert_eq!(ldf.diagnostic_frames[1].signals.len(), 8);
383 assert_eq!(ldf.diagnostic_frames[1].signals[0].signal_name, "SlaveRespB0");
384 assert_eq!(ldf.diagnostic_frames[1].signals[0].start_bit, 0);
385 assert_eq!(ldf.diagnostic_frames[1].signals[7].signal_name, "SlaveRespB7");
386 assert_eq!(ldf.diagnostic_frames[1].signals[7].start_bit, 56);
387
388 assert_eq!(ldf.node_attributes.len(), 2);
390 assert_eq!(ldf.node_attributes[0].node_name, "Slave1");
391 assert_eq!(ldf.node_attributes[0].lin_protocol, "2.1");
392 assert_eq!(ldf.node_attributes[0].configured_nad, 0xB);
393 assert_eq!(ldf.node_attributes[0].initial_nad, 0xB);
394 assert_eq!(ldf.node_attributes[0].supplier_id, 0x123);
395 assert_eq!(ldf.node_attributes[0].function_id, 0x4567);
396 assert_eq!(ldf.node_attributes[0].variant, 8);
397 assert_eq!(ldf.node_attributes[0].response_error, "Signal1");
398 assert_eq!(ldf.node_attributes[0].p2_min, "100 ms");
399 assert_eq!(ldf.node_attributes[0].st_min, "0 ms");
400 assert_eq!(ldf.node_attributes[0].n_as_timeout, "1000 ms");
401 assert_eq!(ldf.node_attributes[0].n_cr_timeout, "1000 ms");
402 assert_eq!(ldf.node_attributes[0].configurable_frames.len(), 2);
403 assert_eq!(ldf.node_attributes[0].configurable_frames[0], "Frame1");
404 assert_eq!(ldf.node_attributes[0].configurable_frames[1], "Frame2");
405 assert_eq!(ldf.node_attributes[1].node_name, "Slave2");
406 assert_eq!(ldf.node_attributes[1].lin_protocol, "2.1");
407 assert_eq!(ldf.node_attributes[1].configured_nad, 0xC);
408 assert_eq!(ldf.node_attributes[1].initial_nad, 0xC);
409 assert_eq!(ldf.node_attributes[1].supplier_id, 0x124);
410 assert_eq!(ldf.node_attributes[1].function_id, 0x4568);
411 assert_eq!(ldf.node_attributes[1].variant, 0x66);
412 assert_eq!(ldf.node_attributes[1].response_error, "Signal2");
413 assert_eq!(ldf.node_attributes[1].p2_min, "100 ms");
414 assert_eq!(ldf.node_attributes[1].st_min, "0 ms");
415 assert_eq!(ldf.node_attributes[1].n_as_timeout, "1000 ms");
416 assert_eq!(ldf.node_attributes[1].n_cr_timeout, "1000 ms");
417 assert_eq!(ldf.node_attributes[1].configurable_frames.len(), 2);
418 assert_eq!(ldf.node_attributes[1].configurable_frames[0], "Frame1");
419 assert_eq!(ldf.node_attributes[1].configurable_frames[1], "Frame2");
420
421 assert_eq!(ldf.schedule_tables.len(), 1);
423 assert_eq!(ldf.schedule_tables[0].schedule_table_name, "AllFrames");
424 assert_eq!(ldf.schedule_tables[0].frame_delays.len(), 2);
425 assert_eq!(ldf.schedule_tables[0].frame_delays[0].frame_name, "Frame1");
426 assert_eq!(ldf.schedule_tables[0].frame_delays[0].frame_time, 10.0);
427 assert_eq!(ldf.schedule_tables[0].frame_delays[1].frame_name, "Frame2");
428 assert_eq!(ldf.schedule_tables[0].frame_delays[1].frame_time, 10.0);
429
430 assert_eq!(ldf.signal_encoding_types.len(), 3);
432 assert_eq!(ldf.signal_encoding_types[0].encoding_type_name, "ENC_BOOL");
433 assert_eq!(ldf.signal_encoding_types[0].encoding_type_values.len(), 2);
434
435 assert_eq!(ldf.signal_representations.len(), 3);
437 assert_eq!(ldf.signal_representations[0].encoding_type_name, "ENC_BOOL");
438 assert_eq!(ldf.signal_representations[0].signal_names.len(), 2);
439 assert_eq!(ldf.signal_representations[0].signal_names[0], "Signal1");
440 assert_eq!(ldf.signal_representations[0].signal_names[1], "Signal2");
441 }
442}