fn parse_sd_data()

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)),
    }
}