fn parse_cef_line(s: &str) -> Result<CefLine> {
    if !s.to_lowercase().contains("cef:0|") {
        // if we dont have the cef and version, then we are
        // not dealing with a cef string
        return Err(Error::NotCef);
    }
    if s.matches('|').count().lt(&7) {
        // Malformed CEF as the header is not complete
        return Err(Error::MalformedCef);
    }

    // resulting struct
    let mut res = CefLine::default();

    // form the cef header
    let arr = s
        .split("CEF:0")
        .filter(|&x| !x.is_empty())
        .collect::<Vec<_>>();
    let header = arr
        .last()
        .unwrap()
        .rsplitn(2, '|')
        .take(2)
        .collect::<Vec<_>>()[1]
        .split('|')
        .skip(1)
        .map(|x| x.trim().to_string());
    res.cef_header = CEF_HEADERS
        .into_iter()
        .map(|x| x.to_string())
        .zip(header.into_iter())
        .collect();

    // form the cef extension
    res.cef_ext = arr
        .last()
        .unwrap()
        .rsplitn(2, '|')
        .take(2)
        .collect::<Vec<_>>()[0]
        .to_string();

    // we mostly have syslog information
    if arr.len().eq(&2) {
        let syslog_data = arr.first().unwrap().trim();
        let data;
        // we might have syslog facility & priority to extract
        if syslog_data.starts_with('<') && syslog_data.contains('>') {
            let pri = &syslog_data[1..syslog_data.find('>').unwrap()];
            if let Ok(parsed) = pri.parse::<i16>() {
                res.syslog_facility = Some((parsed >> 3).to_string());
                res.syslog_priority = Some((parsed & 7).to_string());
            }
            data = &syslog_data[syslog_data.find('>').unwrap() + 1..];
        } else {
            // no syslog facility & priority
            data = syslog_data;
        }

        // see if host and/or datetime is found and extract
        // 1 space means we have hostname/ip and/or datetime
        // more than 1 space- taking for granted that it could be
        // a human readable datetime string & may/not be hostname
        if data.matches(' ').count().eq(&1) {
            let x = data
                .rsplitn(2, ' ')
                .filter(|&x| !x.is_empty())
                .collect::<Vec<_>>();
            if x.len().eq(&2) {
                // we have hostname & date
                res.ahost = x.first().map(|x| x.to_string());
                res.at = x.last().map(|x| x.to_string());
            } else if x.len().eq(&1) {
                // Malformed Syslog - We either have a host or datetime
                let ss = x.first().unwrap();
                // need to check if its datetime/hostname
                if is_datetime_str(ss) {
                    res.at = Some(ss.to_string())
                } else {
                    res.ahost = Some(ss.to_string())
                }
            }
        } else if data.matches(' ').count().eq(&2) {
            // assuming that this is only a human date string
            res.at = Some(data.to_string())
        } else if data.matches(' ').count().gt(&2) {
            // assuming that this could be a human datetime string + host
            let x = data
                .rsplitn(2, ' ')
                .filter(|&x| !x.is_empty())
                .collect::<Vec<_>>();
            res.ahost = x.first().map(|x| x.to_string());
            res.at = x.last().map(|x| x.to_string());
        } else if data.matches(' ').count().eq(&0) {
            // need to check if its datetime/hostname
            if is_datetime_str(data) {
                res.at = Some(data.to_string())
            } else {
                res.ahost = Some(data.to_string())
            }
        }
    }

    Ok(res)
}
/// Parse the given cef string to a struct of fields
/// which will further be used for forming the map with ease
Parse the given cef string to a struct of fields
which will further be used for forming the map with ease
Parse the given cef string to a struct of fields which will further be used for forming the map with ease
fn parse_cef_line(s: &str) -> Result<CefLine> {
    if !s.to_lowercase().contains("cef:0|") {
        // if we dont have the cef and version, then we are
        // not dealing with a cef string
        return Err(Error::NotCef);
    }
    if s.matches('|').count().lt(&7) {
        // Malformed CEF as the header is not complete
        return Err(Error::MalformedCef);
    }
    // resulting struct
    let mut res = CefLine::default();
    // form the cef header
    let arr = s
        .split("CEF:0")
        .filter(|&x| !x.is_empty())
        .collect::<Vec<_>>();
    let header = arr
        .last()
        .unwrap()
        .rsplitn(2, '|')
        .take(2)
        .collect::<Vec<_>>()[1]
        .split('|')
        .skip(1)
        .map(|x| x.trim().to_string());
    res.cef_header = CEF_HEADERS
        .into_iter()
        .map(|x| x.to_string())
        .zip(header.into_iter())
        .collect();
    // form the cef extension
    res.cef_ext = arr
        .last()
        .unwrap()
        .rsplitn(2, '|')
        .take(2)
        .collect::<Vec<_>>()[0]
        .to_string();
    // we mostly have syslog information
    if arr.len().eq(&2) {
        let syslog_data = arr.first().unwrap().trim();
        let data;
        // we might have syslog facility & priority to extract
        if syslog_data.starts_with('<') && syslog_data.contains('>') {
            let pri = &syslog_data[1..syslog_data.find('>').unwrap()];
            if let Ok(parsed) = pri.parse::<i16>() {
                res.syslog_facility = Some((parsed >> 3).to_string());
                res.syslog_priority = Some((parsed & 7).to_string());
            }
            data = &syslog_data[syslog_data.find('>').unwrap() + 1..];
        } else {
            // no syslog facility & priority
            data = syslog_data;
        }
        // see if host and/or datetime is found and extract
        // 1 space means we have hostname/ip and/or datetime
        // more than 1 space- taking for granted that it could be
        // a human readable datetime string & may/not be hostname
        if data.matches(' ').count().eq(&1) {
            let x = data
                .rsplitn(2, ' ')
                .filter(|&x| !x.is_empty())
                .collect::<Vec<_>>();
            if x.len().eq(&2) {
                // we have hostname & date
                res.ahost = x.first().map(|x| x.to_string());
                res.at = x.last().map(|x| x.to_string());
            } else if x.len().eq(&1) {
                // Malformed Syslog - We either have a host or datetime
                let ss = x.first().unwrap();
                // need to check if its datetime/hostname
                if is_datetime_str(ss) {
                    res.at = Some(ss.to_string())
                } else {
                    res.ahost = Some(ss.to_string())
                }
            }
        } else if data.matches(' ').count().eq(&2) {
            // assuming that this is only a human date string
            res.at = Some(data.to_string())
        } else if data.matches(' ').count().gt(&2) {
            // assuming that this could be a human datetime string + host
            let x = data
                .rsplitn(2, ' ')
                .filter(|&x| !x.is_empty())
                .collect::<Vec<_>>();
            res.ahost = x.first().map(|x| x.to_string());
            res.at = x.last().map(|x| x.to_string());
        } else if data.matches(' ').count().eq(&0) {
            // need to check if its datetime/hostname
            if is_datetime_str(data) {
                res.at = Some(data.to_string())
            } else {
                res.ahost = Some(data.to_string())
            }
        }
    }
    Ok(res)
}
fn parse_cef_line ( s : & str ) -> Result < CefLine > { if ! s . to_lowercase ( ) . contains ( " " ) { // if we dont have the cef and version, then we are // not dealing with a cef string return Err ( Error :: NotCef ) ; } if s . matches ( '|' ) . count ( ) . lt ( & 7 ) { // Malformed CEF as the header is not complete return Err ( Error :: MalformedCef ) ; } // resulting struct let mut res = CefLine :: default ( ) ; // form the cef header let arr = s . split ( " " ) . filter ( | & x | ! x . is_empty ( ) ) . collect :: < Vec < _ > > ( ) ; let header = arr . last ( ) . unwrap ( ) . rsplitn ( 2 , '|' ) . take ( 2 ) . collect :: < Vec < _ > > ( ) [ 1 ] . split ( '|' ) . skip ( 1 ) . map ( | x | x . trim ( ) . to_string ( ) ) ; res . cef_header = CEF_HEADERS . into_iter ( ) . map ( | x | x . to_string ( ) ) . zip ( header . into_iter ( ) ) . collect ( ) ; // form the cef extension res . cef_ext = arr . last ( ) . unwrap ( ) . rsplitn ( 2 , '|' ) . take ( 2 ) . collect :: < Vec < _ > > ( ) [ 0 ] . to_string ( ) ; // we mostly have syslog information if arr . len ( ) . eq ( & 2 ) { let syslog_data = arr . first ( ) . unwrap ( ) . trim ( ) ; let data ; // we might have syslog facility & priority to extract if syslog_data . starts_with ( '<' ) && syslog_data . contains ( '>' ) { let pri = & syslog_data [ 1 .. syslog_data . find ( '>' ) . unwrap ( ) ] ; if let Ok ( parsed ) = pri . parse :: < i16 > ( ) { res . syslog_facility = Some ( ( parsed >> 3 ) . to_string ( ) ) ; res . syslog_priority = Some ( ( parsed & 7 ) . to_string ( ) ) ; } data = & syslog_data [ syslog_data . find ( '>' ) . unwrap ( ) + 1 .. ] ; } else { // no syslog facility & priority data = syslog_data ; } // see if host and/or datetime is found and extract // 1 space means we have hostname/ip and/or datetime // more than 1 space- taking for granted that it could be // a human readable datetime string & may/not be hostname if data . matches ( ' ' ) . count ( ) . eq ( & 1 ) { let x = data . rsplitn ( 2 , ' ' ) . filter ( | & x | ! x . is_empty ( ) ) . collect :: < Vec < _ > > ( ) ; if x . len ( ) . eq ( & 2 ) { // we have hostname & date res . ahost = x . first ( ) . map ( | x | x . to_string ( ) ) ; res . at = x . last ( ) . map ( | x | x . to_string ( ) ) ; } else if x . len ( ) . eq ( & 1 ) { // Malformed Syslog - We either have a host or datetime let ss = x . first ( ) . unwrap ( ) ; // need to check if its datetime/hostname if is_datetime_str ( ss ) { res . at = Some ( ss . to_string ( ) ) } else { res . ahost = Some ( ss . to_string ( ) ) } } } else if data . matches ( ' ' ) . count ( ) . eq ( & 2 ) { // assuming that this is only a human date string res . at = Some ( data . to_string ( ) ) } else if data . matches ( ' ' ) . count ( ) . gt ( & 2 ) { // assuming that this could be a human datetime string + host let x = data . rsplitn ( 2 , ' ' ) . filter ( | & x | ! x . is_empty ( ) ) . collect :: < Vec < _ > > ( ) ; res . ahost = x . first ( ) . map ( | x | x . to_string ( ) ) ; res . at = x . last ( ) . map ( | x | x . to_string ( ) ) ; } else if data . matches ( ' ' ) . count ( ) . eq ( & 0 ) { // need to check if its datetime/hostname if is_datetime_str ( data ) { res . at = Some ( data . to_string ( ) ) } else { res . ahost = Some ( data . to_string ( ) ) } } } Ok ( res ) }
Parse the given cef string to a struct of fields
which will further be used for forming the map with ease
Parse the given cef string to a struct of fields which will further be used for forming the map with ease
s
&str
s
&str