openpql-runner 0.1.3

A high-performance Rust implementation of Poker Query Language (PQL), enabling SQL-like queries for poker analysis and calculations. This project is a spiritual successor to the original Java implementation developed by Odds Oracle.
Documentation
use super::*;

pub fn push_num(
    data: &mut CompilerData,
    num: &ast::Num,
    expected_type: PQLType,
) -> PQLResult<PQLType> {
    let (value, rtn_type) = match (expected_type, num.inner) {
        (PQLType::CARDCOUNT, ast::NumValue::Int(long)) => {
            match PQLCardCount::try_from(long) {
                Ok(v) => (v.into(), PQLType::CARDCOUNT),
                Err(_) => {
                    return Err(mk_err(num, PQLErrorKind::InvalidCardCount));
                }
            }
        }
        (_, ast::NumValue::Int(long)) => (long.into(), PQLType::LONG),
        (_, ast::NumValue::Float(float)) => (float.into(), PQLType::DOUBLE),
    };

    data.prog.push((VmInstruction::Push(value), num.loc));

    Ok(rtn_type)
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::*;

    fn assert_num(
        type_hint: PQLType,
        src: &str,
        expected: VmStackValue,
        expected_type: PQLType,
    ) {
        let expr = parse_num(src).unwrap();

        let mut data = CompilerData::default();

        let tp = push_num(&mut data, &expr, type_hint).unwrap();

        assert_eq!(data.prog[0].0, VmInstruction::Push(expected));
        assert_eq!(tp, expected_type);
    }

    fn assert_err<E>(expected_type: PQLType, src: &str, err: E)
    where
        PQLErrorKind: From<E>,
    {
        let expr = parse_num(src).unwrap();

        let mut data = CompilerData::default();

        assert_eq!(
            push_num(&mut data, &expr, expected_type),
            Err(mk_err(&expr, err))
        );
    }

    #[test]
    fn test_num_with_type_hint() {
        assert_num(
            PQLType::CARDCOUNT,
            "1",
            sval!(@count 1),
            PQLType::CARDCOUNT,
        );
        assert_num(PQLType::LONG, "-1", sval!(@long -1), PQLType::LONG);
        assert_num(PQLType::DOUBLE, "0.1", 0.1.into(), PQLType::DOUBLE);
    }

    #[test]
    fn test_num_without_type_hint() {
        assert_num(PQLType::all(), "1", sval!(@long 1), PQLType::LONG);
        assert_num(PQLType::all(), "-1", sval!(@long -1), PQLType::LONG);
        assert_num(PQLType::all(), "0.1", 0.1.into(), PQLType::DOUBLE);
    }

    #[test]
    fn test_num_err() {
        let toobig = "256";
        assert_err(PQLType::CARDCOUNT, toobig, PQLErrorKind::InvalidCardCount);
    }
}