use super::BitTiming;
use crate::{BS_, Parser, Result};
impl BitTiming {
#[must_use = "parse result should be checked"]
pub(crate) fn parse(parser: &mut Parser) -> Result<Self> {
parser.expect(BS_.as_bytes())?;
parser.skip_whitespace().ok();
parser.expect(b":")?;
parser.skip_whitespace().ok();
if parser.at_newline() || parser.is_empty() {
return Ok(BitTiming::new());
}
let baudrate = match parser.parse_u32() {
Ok(b) => b,
Err(_) => return Ok(BitTiming::new()), };
parser.skip_whitespace().ok();
if parser.at_newline() || parser.is_empty() {
return Ok(BitTiming::with_baudrate(baudrate));
}
if parser.expect(b":").is_err() {
return Ok(BitTiming::with_baudrate(baudrate));
}
parser.skip_whitespace().ok();
let mut btr1 = 0u32;
let mut found_btr1_digits = false;
loop {
if parser.eof() {
break;
}
let Some(b) = parser.current_byte() else {
break;
};
if b.is_ascii_digit() {
found_btr1_digits = true;
btr1 = btr1.wrapping_mul(10).wrapping_add((b - b'0') as u32);
parser.advance_one();
} else {
break;
}
}
if !found_btr1_digits {
return Ok(BitTiming::with_baudrate(baudrate));
}
parser.skip_whitespace().ok();
if parser.expect(b",").is_err() {
return Ok(BitTiming::with_baudrate(baudrate));
}
parser.skip_whitespace().ok();
let mut btr2 = 0u32;
let mut found_btr2_digits = false;
loop {
if parser.eof() {
break;
}
let Some(b) = parser.current_byte() else {
break;
};
if b.is_ascii_digit() {
found_btr2_digits = true;
btr2 = btr2.wrapping_mul(10).wrapping_add((b - b'0') as u32);
parser.advance_one();
} else {
break;
}
}
if !found_btr2_digits {
return Ok(BitTiming::with_baudrate(baudrate));
}
Ok(BitTiming::with_btr(baudrate, btr1, btr2))
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_parse_empty() {
let mut parser = Parser::new(b"BS_:").unwrap();
let bt = BitTiming::parse(&mut parser).unwrap();
assert!(bt.is_empty());
assert_eq!(bt.baudrate(), None);
assert_eq!(bt.btr1(), None);
assert_eq!(bt.btr2(), None);
}
#[test]
fn test_parse_empty_with_newline() {
let mut parser = Parser::new(b"BS_:\n").unwrap();
let bt = BitTiming::parse(&mut parser).unwrap();
assert!(bt.is_empty());
}
#[test]
fn test_parse_baudrate_only() {
let mut parser = Parser::new(b"BS_: 500").unwrap();
let bt = BitTiming::parse(&mut parser).unwrap();
assert!(!bt.is_empty());
assert_eq!(bt.baudrate(), Some(500));
assert_eq!(bt.btr1(), None);
assert_eq!(bt.btr2(), None);
}
#[test]
fn test_parse_full() {
let mut parser = Parser::new(b"BS_: 500 : 12,34").unwrap();
let bt = BitTiming::parse(&mut parser).unwrap();
assert!(!bt.is_empty());
assert_eq!(bt.baudrate(), Some(500));
assert_eq!(bt.btr1(), Some(12));
assert_eq!(bt.btr2(), Some(34));
}
#[test]
fn test_parse_full_no_spaces() {
let mut parser = Parser::new(b"BS_:500:12,34").unwrap();
let bt = BitTiming::parse(&mut parser).unwrap();
assert_eq!(bt.baudrate(), Some(500));
assert_eq!(bt.btr1(), Some(12));
assert_eq!(bt.btr2(), Some(34));
}
#[test]
fn test_parse_full_with_newline() {
let mut parser = Parser::new(b"BS_: 500 : 12,34\n").unwrap();
let bt = BitTiming::parse(&mut parser).unwrap();
assert_eq!(bt.baudrate(), Some(500));
assert_eq!(bt.btr1(), Some(12));
assert_eq!(bt.btr2(), Some(34));
}
}