use super::Signal;
use std::{
fmt::{Display, Formatter, Result},
string::String,
};
impl Signal {
#[must_use = "return value should be used"]
pub fn to_dbc_string(&self) -> String {
let mut result = String::with_capacity(100);
result.push_str(" SG_ ");
result.push_str(self.name());
result.push_str(" : ");
result.push_str(&self.start_bit().to_string());
result.push('|');
result.push_str(&self.length().to_string());
result.push('@');
match self.byte_order() {
crate::ByteOrder::BigEndian => result.push('0'), crate::ByteOrder::LittleEndian => result.push('1'), }
if self.is_unsigned() {
result.push('+');
} else {
result.push('-');
}
result.push_str(" (");
use core::fmt::Write;
write!(result, "{}", self.factor()).unwrap();
result.push(',');
write!(result, "{}", self.offset()).unwrap();
result.push(')');
result.push_str(" [");
write!(result, "{}", self.min()).unwrap();
result.push('|');
write!(result, "{}", self.max()).unwrap();
result.push(']');
result.push(' ');
if let Some(unit) = self.unit() {
result.push('"');
result.push_str(unit);
result.push('"');
} else {
result.push_str("\"\"");
}
result.push(' ');
result.push_str(&self.receivers().to_dbc_string());
result
}
}
impl Display for Signal {
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
write!(f, "{}", self.to_dbc_string())
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::Parser;
#[test]
fn test_signal_to_dbc_string_round_trip() {
let test_cases = vec![
(
r#"SG_ RPM : 0|16@0+ (0.25,0) [0|8000] "rpm" *"#,
" SG_ RPM : 0|16@0+ (0.25,0) [0|8000] \"rpm\" Vector__XXX",
),
(
r#"SG_ Temperature : 16|8@1- (1,-40) [-40|215] "°C" TCM BCM"#,
" SG_ Temperature : 16|8@1- (1,-40) [-40|215] \"°C\" TCM,BCM",
),
(
r#"SG_ Flag : 24|1@0+ (1,0) [0|1] "" *"#,
" SG_ Flag : 24|1@0+ (1,0) [0|1] \"\" Vector__XXX",
),
];
for (input_line, expected_output) in test_cases {
let mut parser = Parser::new(input_line.as_bytes()).unwrap();
let signal = Signal::parse(&mut parser).unwrap();
let dbc_string = signal.to_dbc_string();
assert_eq!(dbc_string, expected_output);
let mut parser2 = Parser::new(dbc_string.as_bytes()).unwrap();
parser2.skip_newlines_and_spaces();
let signal2 = Signal::parse(&mut parser2).unwrap();
assert_eq!(signal.name(), signal2.name());
assert_eq!(signal.start_bit(), signal2.start_bit());
assert_eq!(signal.length(), signal2.length());
assert_eq!(signal.byte_order(), signal2.byte_order());
assert_eq!(signal.is_unsigned(), signal2.is_unsigned());
assert_eq!(signal.factor(), signal2.factor());
assert_eq!(signal.offset(), signal2.offset());
assert_eq!(signal.min(), signal2.min());
assert_eq!(signal.max(), signal2.max());
assert_eq!(signal.unit(), signal2.unit());
}
}
}