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