opql/
lib.rs

1#![cfg_attr(coverage_nightly, feature(coverage_attribute))]
2#![cfg_attr(test, allow(clippy::needless_pass_by_value))]
3#![cfg_attr(test, allow(clippy::missing_panics_doc))]
4#![allow(clippy::wildcard_imports)]
5#![allow(unused_imports)]
6
7use std::{
8    any::Any,
9    borrow::Borrow,
10    cmp, convert, fmt, io, mem,
11    num::{ParseFloatError, ParseIntError},
12    ops, ptr,
13    rc::Rc,
14    str::FromStr,
15};
16
17use bitflags::bitflags;
18use derive_more::{Display, Into, TryInto};
19use openpql_macro::*;
20pub use openpql_pql_parser::parse_pql;
21use openpql_pql_parser::{Error as SyntaxError, *};
22use openpql_prelude::{CardGen, HandN, ParseError, PlayerIdx};
23use openpql_range_parser::{
24    BoardRangeChecker, Error as RangeError, RangeChecker,
25};
26use runner_output::*;
27
28mod error;
29mod output_aggregator;
30mod runner_output;
31// TODO: remove
32#[cfg_attr(coverage_nightly, coverage(off))]
33mod functions;
34mod helper_loc;
35mod runner;
36mod types;
37mod util;
38mod vm;
39
40pub use error::*;
41use functions::*;
42use helper_loc::*;
43use output_aggregator::*;
44pub use runner::*;
45#[cfg(test)]
46pub use tests::*;
47pub use types::*;
48use util::*;
49use vm::{
50    Vm, VmBinOpCmp, VmCache, VmExecContext, VmProgram, VmSampledData,
51    VmStackValue,
52};
53
54type HeapIdx = usize;
55type FractionInner = u8;
56type RangeSrc = String;
57type FnCheckRange = Box<dyn Fn(&[PQLCard]) -> bool>;
58
59fn parse_cards(text: &str) -> Option<PQLCardSet> {
60    let mut res = PQLCardSet::default();
61    let mut iter = text.chars().filter(|c| !c.is_whitespace());
62
63    while let Some(rank) = iter.next() {
64        let suit = iter.next()?;
65
66        dbg!(suit);
67        res.set(PQLCard::new(
68            PQLRank::from_char(rank)?,
69            PQLSuit::from_char(suit)?,
70        ));
71    }
72
73    Some(res)
74}
75
76#[cfg(test)]
77pub mod tests {
78    pub use std::fmt::Write;
79
80    pub use itertools::Itertools;
81    use openpql_pql_parser::*;
82    pub use openpql_prelude::{CardN, c64, card, cards, r16};
83    pub use quickcheck::{Arbitrary, TestResult};
84    pub use quickcheck_macros::quickcheck;
85    pub use rand::{SeedableRng, prelude::*, rngs};
86
87    pub use super::{
88        PQLBoardRange, PQLGame, PQLHiRating, PQLRange,
89        functions::{PQLFnContext, TestPQLFnContext, rate_hi_hand},
90    };
91    use super::{PQLCard, PQLCardCount, PQLError, PQLErrorKind, PQLRank};
92
93    pub fn count_suits(cs: &[PQLCard]) -> PQLCardCount {
94        cs.iter().map(|c| c.suit).unique().count().to_le_bytes()[0]
95    }
96
97    pub fn get_ranks(cs: &[PQLCard]) -> Vec<PQLRank> {
98        cs.iter().map(|c| c.rank).collect()
99    }
100
101    pub fn mk_ranges(
102        game: PQLGame,
103        player: &[&str],
104        board: &str,
105    ) -> (Vec<PQLRange>, PQLBoardRange) {
106        let player_ranges = player
107            .iter()
108            .map(|&s| (game, s).try_into().unwrap())
109            .collect();
110
111        let board_range = (game, board).try_into().unwrap();
112
113        (player_ranges, board_range)
114    }
115
116    pub fn mk_rating(text: &str) -> PQLHiRating {
117        rate_hi_hand(&PQLFnContext::default(), &text.to_string()).unwrap()
118    }
119}