wp-lang 0.1.8

WPL language crate with AST, parser, evaluator, builtins, and generators.
Documentation
use crate::WplSep;
use crate::ast::group::GroupAlt;
use crate::eval::runtime::group::{LogicProc, WplEvalGroup};
use winnow::stream::Stream;
use wp_log::trace_edata;
use wp_model_core::model::DataField;
use wp_primitives::WResult as ModalResult;

impl LogicProc for GroupAlt {
    fn process(
        &self,
        e_id: u64,
        group: &WplEvalGroup,
        ups_sep: &WplSep,
        data: &mut &str,
        out: &mut Vec<DataField>,
    ) -> ModalResult<()> {
        alt_proc(e_id, group, ups_sep, data, out)
    }
}

pub fn alt_proc(
    e_id: u64,
    group: &WplEvalGroup,
    ups_sep: &WplSep,
    data: &mut &str,
    out: &mut Vec<DataField>,
) -> ModalResult<()> {
    let mut last_err = None;
    let mut min_left_len = data.len();
    let cur_sep = group.combo_sep(ups_sep);
    for fpu in group.field_units.iter() {
        if data.is_empty() {
            break;
        }
        let ck_point = data.checkpoint();
        match fpu.parse(e_id, &cur_sep, data, Some(fpu.conf().safe_name()), out) {
            Ok(_) => {
                return Ok(());
            }
            Err(e) => {
                trace_edata!(e_id, "fpu parse error {} {} \n{}", fpu.conf(), e, data);
                let cur_pos = data.len();
                if cur_pos < min_left_len || last_err.is_none() {
                    last_err = Some(e);
                    min_left_len = cur_pos;
                }
                data.reset(&ck_point);
                continue;
            }
        }
    }
    match last_err {
        None => Ok(()),
        Some(e) => Err(e),
    }
}

#[cfg(test)]
mod tests {
    use crate::types::AnyResult;
    use crate::{WplEvaluator, wpl_express};
    use orion_error::TestAssert;
    use std::net::{IpAddr, Ipv4Addr};
    use wp_model_core::model::DataField;
    use wp_primitives::Parser;

    #[test]
    fn test_alt_group() -> AnyResult<()> {
        let express = wpl_express
            .parse(r#"alt(ip:sip,digit:id),(2*_,time<[,]>)"#)
            .assert();
        let mut data = r#"192.168.1.2 - - [06/Aug/2019:12:12:19 +0800] "#;
        let ppl = WplEvaluator::from(&express, None)?;

        let result = ppl.parse_groups(0, &mut data).assert();
        assert_eq!(data, "");
        println!("{}", result);
        assert_eq!(
            result.get_field_owned("sip"),
            Some(DataField::from_ip(
                "sip",
                IpAddr::V4(Ipv4Addr::new(192, 168, 1, 2))
            ))
        );

        let mut data = r#"2002 - - [06/Aug/2019:12:12:19 +0800] "#;
        let result = ppl.parse_groups(0, &mut data).assert();
        assert_eq!(data, "");
        println!("{}", result);
        assert_eq!(
            result.get_field_owned("id"),
            Some(DataField::from_digit("id", 2002))
        );

        let mut data = r#"bad - - [06/Aug/2019:12:12:19 +0800] "#;
        let result = ppl.parse_groups(0, &mut data);
        assert!(result.is_err());
        Ok(())
    }
}