in src/flowgger/decoder/rfc5424_decoder.rs [165:233]
fn parse_sd_data(line: &str, offset: usize) -> Result<(StructuredData, &str, usize), &'static str> {
let mut parts = line[offset..].splitn(2, ' ');
let sd_id = parts.next().ok_or("Missing structured data id")?;
let sd = parts.next().ok_or("Missing structured data")?;
let mut in_name = false;
let mut in_value = false;
let mut name_start = 0;
let mut value_start = 0;
let mut name: Option<&str> = None;
let mut esc = false;
let mut after_sd: Option<usize> = None;
let mut sd_res = StructuredData::new(Some(sd_id));
for (i, c) in sd.char_indices() {
let is_sd_name = match c as u32 {
32 | 34 | 61 | 93 => false,
33..=126 => true,
_ => false,
};
match (c, esc, is_sd_name, in_name, name.is_some(), in_value) {
(' ', false, _, false, false, _) => {
// contextless spaces
}
(']', false, _, false, false, _) => {
after_sd = Some(i + 1);
break;
}
(_, false, true, false, false, _) => {
in_name = true;
name_start = i;
}
(_, _, true, true, false, _) => {
// name
}
('=', false, _, true, ..) => {
name = Some(&sd[name_start..i]);
in_name = false;
}
('"', false, _, _, true, false) => {
in_value = true;
value_start = i + 1;
}
('\\', false, _, _, _, true) => esc = true,
('"', false, _, _, _, true) => {
in_value = false;
let value = unescape_sd_value(&sd[value_start..i]);
let pair = (
"_".to_owned()
+ name.expect(
"Name in structured data contains an invalid UTF-8 \
sequence",
),
SDValue::String(value),
);
sd_res.pairs.push(pair);
name = None;
}
(_, _, _, _, _, true) => esc = false,
('"', false, _, false, false, _) => {
// tolerate bogus entries with extra "
}
_ => return Err("Format error in the structured data"),
}
}
match after_sd {
None => Err("Missing ] after structured data"),
Some(offset) => Ok((sd_res, sd, offset)),
}
}