1use std::fmt;
2
3use nom::branch::alt;
4use nom::bytes::complete::tag;
5use nom::character::complete::line_ending;
6use nom::combinator::{map, opt};
7use nom::multi::{many0, separated_list0};
8use nom::sequence::{delimited, pair, separated_pair};
9use nom::{IResult, Parser};
10
11use super::char_string::{parser_char_string, CharString};
12use super::common_parsers::{
13 multispacey, number_value, parser_node_name, parser_signal_name, spacey, unsigned_integer,
14};
15use super::error::DbcParseError;
16
17#[derive(PartialEq, Debug, Clone)]
38#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
39pub struct MultiplexerIndicator {
40 pub multiplexer_signal: Option<u32>,
43 pub multiplexer_switch: Option<()>,
45}
46
47impl fmt::Display for MultiplexerIndicator {
48 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
49 if let Some(multiplexer_signal) = self.multiplexer_signal {
50 write!(f, "m{multiplexer_signal}")?;
51 }
52 if let Some(()) = self.multiplexer_switch {
53 write!(f, "M")?;
54 }
55 Ok(())
56 }
57}
58
59#[derive(PartialEq, Debug, Clone)]
61#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
62pub enum ByteOrder {
63 LittleEndian,
64 BigEndian,
65}
66
67impl fmt::Display for ByteOrder {
68 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
69 match self {
70 ByteOrder::LittleEndian => write!(f, "1"),
71 ByteOrder::BigEndian => write!(f, "0"),
72 }
73 }
74}
75
76#[derive(PartialEq, Debug, Clone)]
78#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
79pub enum ValueType {
80 Signed,
81 Unsigned,
82}
83
84impl fmt::Display for ValueType {
85 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
86 match self {
87 ValueType::Signed => write!(f, "-"),
88 ValueType::Unsigned => write!(f, "+"),
89 }
90 }
91}
92
93#[derive(PartialEq, Debug, Clone)]
122#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
123pub struct Signal {
124 pub name: String,
125 pub multiplexer: Option<MultiplexerIndicator>,
126 pub start_bit: u32,
127 pub size: u32,
128 pub byte_order: ByteOrder,
129 pub value_type: ValueType,
130 pub factor: f64,
131 pub offset: f64,
132 pub min: Option<f64>,
133 pub max: Option<f64>,
134 pub unit: Option<CharString>,
135 pub receivers: Option<Vec<String>>,
136}
137
138impl fmt::Display for Signal {
139 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
140 let multiplexer = match &self.multiplexer {
141 Some(m) => format!("{m} "),
142 None => String::new(),
143 };
144 let value_type = match &self.value_type {
145 ValueType::Signed => "-",
146 ValueType::Unsigned => "+",
147 };
148 let byte_order = &self.byte_order.to_string();
149 let min_max = match (&self.min, &self.max) {
150 (Some(min), Some(max)) => format!("[{min}|{max}]"),
151 _ => String::new(),
152 };
153 let unit = match &self.unit {
154 Some(u) => format!(r#""{u}""#),
155 None => String::new(),
156 };
157 let mut receivers_str = String::new();
158 if let Some(nodes) = &self.receivers {
159 receivers_str = nodes.join(",");
160 }
161
162 write!(
163 f,
164 "SG_ {} {}: {}|{}@{}{} ({},{}) {} {} {}",
165 self.name,
166 multiplexer,
167 self.start_bit,
168 self.size,
169 byte_order,
170 value_type,
171 self.factor,
172 self.offset,
173 min_max,
174 unit,
175 receivers_str
176 )
177 }
178}
179
180fn parser_signal_multiplexer(input: &str) -> IResult<&str, MultiplexerIndicator, DbcParseError> {
181 map(
182 (opt(pair(tag("m"), unsigned_integer)), opt(tag("M"))),
183 |(multiplexer_signal, multiplexer_switch)| MultiplexerIndicator {
184 multiplexer_signal: multiplexer_signal.map(|(_, num)| num),
185 multiplexer_switch: multiplexer_switch.map(|_| ()),
186 },
187 )
188 .parse(input)
189}
190
191fn parser_signal_multiplexer_option(
192 input: &str,
193) -> IResult<&str, Option<MultiplexerIndicator>, DbcParseError> {
194 let res = parser_signal_multiplexer(input)?;
195 if res.1.multiplexer_signal.is_none() && res.1.multiplexer_switch.is_none() {
196 return Ok((res.0, None));
197 }
198 Ok((res.0, Some(res.1)))
199}
200
201fn parser_signal_start_bit(input: &str) -> IResult<&str, u32, DbcParseError> {
202 unsigned_integer(input)
203}
204
205fn parser_signal_size(input: &str) -> IResult<&str, u32, DbcParseError> {
206 unsigned_integer(input)
207}
208
209fn parser_signal_byte_order(input: &str) -> IResult<&str, ByteOrder, DbcParseError> {
210 alt((
211 map(tag("1"), |_| ByteOrder::LittleEndian),
212 map(tag("0"), |_| ByteOrder::BigEndian),
213 ))
214 .parse(input)
215}
216
217fn parser_signal_value_type(input: &str) -> IResult<&str, ValueType, DbcParseError> {
218 alt((
219 map(tag("+"), |_| ValueType::Unsigned),
220 map(tag("-"), |_| ValueType::Signed),
221 ))
222 .parse(input)
223}
224
225fn parser_signal_factor_offset(input: &str) -> IResult<&str, (f64, f64), DbcParseError> {
226 let (remain, (factor, offset)) = delimited(
227 spacey(tag("(")),
228 separated_pair(number_value, spacey(tag(",")), number_value),
229 spacey(tag(")")),
230 )
231 .parse(input)?;
232
233 Ok((remain, (factor, offset)))
234}
235
236fn parser_signal_min_max(input: &str) -> IResult<&str, (f64, f64), DbcParseError> {
237 let (remain, (min_value, max_value)) = delimited(
238 spacey(tag("[")),
239 separated_pair(number_value, spacey(tag("|")), number_value),
240 spacey(tag("]")),
241 )
242 .parse(input)?;
243
244 Ok((remain, (min_value, max_value)))
245}
246
247fn parser_signal_unit(input: &str) -> IResult<&str, CharString, DbcParseError> {
248 parser_char_string(input)
249}
250
251fn parser_signal_receivers(input: &str) -> IResult<&str, Vec<String>, DbcParseError> {
252 let (remain, nodes) =
253 spacey(separated_list0(tag(","), spacey(parser_node_name))).parse(input)?;
254 Ok((remain, nodes.into_iter().map(String::from).collect()))
255}
256
257pub fn parser_signal(input: &str) -> IResult<&str, Signal, DbcParseError> {
258 let res = map(
259 (
260 multispacey(tag("SG_")),
261 spacey(parser_signal_name),
262 spacey(parser_signal_multiplexer_option),
263 spacey(tag(":")),
264 spacey(parser_signal_start_bit),
265 spacey(tag("|")),
266 spacey(parser_signal_size),
267 spacey(tag("@")),
268 spacey(parser_signal_byte_order),
269 spacey(parser_signal_value_type),
270 spacey(parser_signal_factor_offset),
271 spacey(opt(parser_signal_min_max)),
272 spacey(opt(parser_signal_unit)),
273 spacey(opt(parser_signal_receivers)),
274 many0(line_ending),
275 ),
276 |(
277 _,
278 name,
279 multiplexer,
280 _,
281 start_bit,
282 _,
283 size,
284 _,
285 byte_order,
286 value_type,
287 factor_offset,
288 min_max,
289 unit,
290 receiving_nodes,
291 _,
292 )| Signal {
293 name: String::from(name),
294 multiplexer,
295 start_bit,
296 size,
297 byte_order,
298 value_type,
299 factor: factor_offset.0,
300 offset: factor_offset.1,
301 min: min_max.map(|(min, _)| min),
302 max: min_max.map(|(_, max)| max),
303 unit,
304 receivers: receiving_nodes,
305 },
306 )
307 .parse(input);
308
309 match res {
310 Ok((remain, signal)) => {
311 log::info!("parse signal: {signal:?}");
312 Ok((remain, signal))
313 }
314 Err(e) => {
315 log::trace!("parse signal failed, e = {e:?}");
316 Err(nom::Err::Error(DbcParseError::BadSignal))
317 }
318 }
319}
320
321#[cfg(test)]
322mod tests {
323 use super::*;
324
325 #[test]
326 fn test_dbc_signal_multiplexer_01() {
327 assert_eq!(
328 parser_signal_multiplexer("M"),
329 Ok((
330 "",
331 MultiplexerIndicator {
332 multiplexer_signal: None,
333 multiplexer_switch: Some(())
334 }
335 )),
336 );
337 }
338
339 #[test]
340 fn test_dbc_signal_multiplexer_02() {
341 assert_eq!(
342 parser_signal_multiplexer("m0"),
343 Ok((
344 "",
345 MultiplexerIndicator {
346 multiplexer_signal: Some(0),
347 multiplexer_switch: None
348 }
349 )),
350 );
351 }
352
353 #[test]
354 fn test_dbc_signal_multiplexer_03() {
355 assert_eq!(
356 parser_signal_multiplexer("m123"),
357 Ok((
358 "",
359 MultiplexerIndicator {
360 multiplexer_signal: Some(123),
361 multiplexer_switch: None
362 }
363 )),
364 );
365 }
366
367 #[test]
368 fn test_dbc_signal_multiplexer_04() {
369 assert_eq!(
370 parser_signal_multiplexer("m3M"),
371 Ok((
372 "",
373 MultiplexerIndicator {
374 multiplexer_signal: Some(3),
375 multiplexer_switch: Some(())
376 }
377 )),
378 );
379 }
380
381 #[test]
382 fn test_dbc_signal_01() {
383 let ret = parser_signal(
384 r#" SG_ AY1 : 32|16@1+ (0.000127465,-4.1768) [-4.1768|4.1765] "g" ABS
385
386"#,
387 );
388 match ret {
389 Ok((_remain, signal)) => {
390 assert_eq!(
391 signal,
392 Signal {
393 name: "AY1".into(),
394 multiplexer: None,
395 start_bit: 32,
396 size: 16,
397 byte_order: ByteOrder::LittleEndian,
398 value_type: ValueType::Unsigned,
399 factor: 0.000_127_465,
400 offset: -4.1768,
401 min: Some(-4.1768),
402 max: Some(4.1765),
403 unit: Some(CharString("g".into())),
404 receivers: Some(vec!["ABS".into()]),
405 }
406 );
407 }
408 Err(err) => panic!("err = {err:?}"),
409 }
410 }
411
412 #[test]
413 fn test_dbc_signal_02() {
414 let ret = parser_signal(
415 r#" SG_ S2 m0 : 8|8@1- (1.0,0.0) [0.0|0.0] "" Vector__XXX
416
417"#,
418 );
419
420 match ret {
421 Ok((_remain, signal)) => {
422 assert_eq!(
423 signal,
424 Signal {
425 name: "S2".into(),
426 multiplexer: Some(MultiplexerIndicator {
427 multiplexer_signal: Some(0),
428 multiplexer_switch: None
429 }),
430 start_bit: 8,
431 size: 8,
432 byte_order: ByteOrder::LittleEndian,
433 value_type: ValueType::Signed,
434 factor: 1.0,
435 offset: 0.0,
436 min: Some(0.0),
437 max: Some(0.0),
438 unit: Some(CharString(String::new())),
439 receivers: Some(vec!["Vector__XXX".into()]),
440 }
441 );
442 }
443 Err(err) => panic!("err = {err:?}"),
444 }
445 }
446
447 #[test]
448 fn test_dbc_signal_03() {
449 let ret = parser_signal(
450 r#" SG_ S2 m0 : 8|8@1- (1,0) [0|0] "" Vector__XXX
451
452"#,
453 );
454
455 match ret {
456 Ok((_remain, signal)) => {
457 assert_eq!(
458 signal,
459 Signal {
460 name: "S2".into(),
461 multiplexer: Some(MultiplexerIndicator {
462 multiplexer_signal: Some(0),
463 multiplexer_switch: None
464 }),
465 start_bit: 8,
466 size: 8,
467 byte_order: ByteOrder::LittleEndian,
468 value_type: ValueType::Signed,
469 factor: 1.0,
470 offset: 0.0,
471 min: Some(0.0),
472 max: Some(0.0),
473 unit: Some(CharString(String::new())),
474 receivers: Some(vec!["Vector__XXX".into()]),
475 }
476 );
477 }
478 Err(err) => panic!("err = {err:?}"),
479 }
480 }
481
482 #[test]
483 fn test_dbc_signal_04() {
484 let ret = parser_signal(
485 r#" SG_ Signal1 : 32|32@1+ (100,0) [0|100] "%" Node1,Node2
486
487"#,
488 );
489
490 match ret {
491 Ok((_remain, signal)) => {
492 assert_eq!(
493 signal,
494 Signal {
495 name: "Signal1".into(),
496 multiplexer: None,
497 start_bit: 32,
498 size: 32,
499 byte_order: ByteOrder::LittleEndian,
500 value_type: ValueType::Unsigned,
501 factor: 100.0,
502 offset: 0.0,
503 min: Some(0.0),
504 max: Some(100.0),
505 unit: Some(CharString("%".into())),
506 receivers: Some(vec!["Node1".into(), "Node2".into()]),
507 }
508 );
509 }
510 Err(err) => panic!("err = {err:?}"),
511 }
512 }
513}