use crate::ldf::ldf_comment::skip_whitespace;
use nom::{
bytes::complete::{tag, take_until, take_while},
IResult,
};
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct LdfNodes {
pub master: MasterNode,
pub slaves: Vec<Node>,
}
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct MasterNode {
pub name: String,
pub time_base: String,
pub jitter: String,
}
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Node {
pub name: String,
}
pub fn parse_ldf_nodes(s: &str) -> IResult<&str, LdfNodes> {
let (s, _) = skip_whitespace(s)?;
let (s, _) = tag("Nodes")(s)?;
let (s, _) = skip_whitespace(s)?;
let (s, _) = tag("{")(s)?;
let (s, _) = skip_whitespace(s)?;
let (s, _) = tag("Master")(s)?;
let (s, _) = skip_whitespace(s)?;
let (s, _) = tag(":")(s)?;
let (s, _) = skip_whitespace(s)?;
let (s, master_node_name) = take_while(|c: char| c.is_alphanumeric() || c == '_')(s)?;
let (s, _) = skip_whitespace(s)?;
let (s, _) = tag(",")(s)?;
let (s, _) = skip_whitespace(s)?;
let (s, time_base) = 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)?;
let (s, jitter) = 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 master = MasterNode {
name: master_node_name.to_string(),
time_base: time_base.to_string() + " ms",
jitter: jitter.to_string() + " ms",
};
let (s, _) = skip_whitespace(s)?;
let (s, _) = tag("Slaves")(s)?;
let (s, _) = skip_whitespace(s)?;
let (s, _) = tag(":")(s)?;
let (s, _) = skip_whitespace(s)?;
let (s, slaves) = take_until(";")(s)?;
let (s, _) = tag(";")(s)?;
let slaves = slaves
.split(",")
.map(|slave| Node {
name: slave.trim().to_string(),
})
.collect();
let (s, _) = skip_whitespace(s)?;
let (s, _) = tag("}")(s)?;
let (s, _) = skip_whitespace(s)?;
Ok((s, LdfNodes { master, slaves }))
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_parse() {
let s = r#"
Nodes {
Master: Master, 5 ms, 0.1 ms ;
Slaves: Slave1, Slave2, Slave3 ;
}
"#;
let (_, header) = parse_ldf_nodes(s).unwrap();
assert_eq!(header.master.name, "Master");
assert_eq!(header.master.time_base, "5 ms");
assert_eq!(header.master.jitter, "0.1 ms");
assert_eq!(header.slaves.len(), 3);
assert_eq!(header.slaves[0].name, "Slave1");
assert_eq!(header.slaves[1].name, "Slave2");
assert_eq!(header.slaves[2].name, "Slave3");
}
}