openpql-range-parser 0.1.0

Poker Range Notation Parser
Documentation
use super::{
    Array, Card, From, Idx, Suit4, VarCondition, VarConditionSuit,
    ast::SuitConst,
};

#[derive(PartialEq, Eq, Debug, Default, Clone)]
pub enum ConstrainSuit<const N: usize>
where
    [Idx; N]: Array<Item = Idx>,
{
    Match(Suit4),
    Var(VarConditionSuit<N>),
    #[default]
    Nil,
}

impl<const N: usize> ConstrainSuit<N>
where
    [Idx; N]: Array<Item = Idx>,
{
    #[inline]
    pub fn reject(&self, cs: &[Card], perm: &[Idx], i: usize) -> bool {
        match self {
            Self::Match(s4) => {
                if !s4.contains_suit(cs[i].suit) {
                    return true;
                }
            }

            Self::Var(VarConditionSuit(VarCondition {
                equal,
                not_equal,
                banned,
                ..
            })) => {
                if banned.contains_suit(cs[i].suit) {
                    return true;
                }

                for original_idx in equal {
                    if let Some(j) = perm.iter().position(|k| original_idx == k)
                        && cs[i].suit != cs[j].suit
                    {
                        return true;
                    }
                }

                for original_idx in not_equal {
                    if let Some(j) = perm.iter().position(|k| original_idx == k)
                        && cs[i].suit == cs[j].suit
                    {
                        return true;
                    }
                }
            }

            Self::Nil => (),
        }

        false
    }
}

impl<const N: usize> From<Option<SuitConst>> for ConstrainSuit<N>
where
    [Idx; N]: Array<Item = Idx>,
{
    fn from(op: Option<SuitConst>) -> Self {
        op.map_or(Self::Nil, Self::from)
    }
}

impl<const N: usize> From<SuitConst> for ConstrainSuit<N>
where
    [Idx; N]: Array<Item = Idx>,
{
    fn from(s: SuitConst) -> Self {
        Self::Match(Suit4::from(1 << s as u8))
    }
}