openpql-runner 0.2.1

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