use crate::ldf::ldf_comment::skip_whitespace;
use nom::{
bytes::complete::{tag, take_while},
IResult,
};
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct LdfScheduleTable {
pub schedule_table_name: String,
pub frame_delays: Vec<LdfFrameDelay>,
}
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct LdfFrameDelay {
pub frame_name: String,
pub frame_time: f32,
}
pub fn parse_ldf_schedule_tables(s: &str) -> IResult<&str, Vec<LdfScheduleTable>> {
let (s, _) = skip_whitespace(s)?;
let (s, _) = tag("Schedule_tables")(s)?;
let (s, _) = skip_whitespace(s)?;
let (s, _) = tag("{")(s)?;
let mut schedule_tables = Vec::new();
let mut remaining = s;
while !remaining.starts_with('}') {
let (s, _) = skip_whitespace(remaining)?;
let (s, schedule_table_name) = take_while(|c: char| c.is_alphanumeric() || c == '_')(s)?;
let (s, _) = skip_whitespace(s)?;
let (s, _) = tag("{")(s)?;
let mut frame_delays = Vec::new();
remaining = s;
while !remaining.starts_with('}') {
let (s, _) = skip_whitespace(remaining)?;
let (s, frame_name) = take_while(|c: char| c.is_alphanumeric() || c == '_')(s)?;
let (s, _) = skip_whitespace(s)?;
let (s, _) = tag("delay")(s)?;
let (s, _) = skip_whitespace(s)?;
let (s, frame_time) = take_while(|c: char| c.is_numeric() || c == '.')(s)?;
let (s, _) = skip_whitespace(s)?;
let (s, _) = tag("ms")(s)?;
let (s, _) = skip_whitespace(s)?;
let (s, _) = tag(";")(s)?;
let (s, _) = skip_whitespace(s)?;
frame_delays.push(LdfFrameDelay {
frame_name: frame_name.to_string(),
frame_time: frame_time.parse().unwrap(),
});
remaining = s;
}
let (s, _) = tag("}")(remaining)?;
let (s, _) = skip_whitespace(s)?;
schedule_tables.push(LdfScheduleTable {
schedule_table_name: schedule_table_name.to_string(),
frame_delays,
});
remaining = s;
}
let (remaining, _) = tag("}")(remaining)?;
Ok((remaining, schedule_tables))
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_parse_ldf_schedule_tables() {
let input = r#"
Schedule_tables {
AllFrames {
Frame1 delay 10 ms ;
Frame2 delay 10.0 ms ;
}
}
"#;
let (_, schedule_tables) = parse_ldf_schedule_tables(input).unwrap();
assert_eq!(schedule_tables.len(), 1);
let schedule_table = &schedule_tables[0];
assert_eq!(schedule_table.schedule_table_name, "AllFrames");
assert_eq!(schedule_table.frame_delays.len(), 2);
let frame_delay = &schedule_table.frame_delays[0];
assert_eq!(frame_delay.frame_name, "Frame1");
assert_eq!(frame_delay.frame_time, 10.0);
let frame_delay = &schedule_table.frame_delays[1];
assert_eq!(frame_delay.frame_name, "Frame2");
assert_eq!(frame_delay.frame_time, 10.0);
}
}