use core::{fmt::Display, hash::Hash};
use itertools::Itertools as _;
pub trait Card:
Copy
+ Display
+ Eq
+ Hash
+ Ord
+ Send
+ Sync
+ 'static
+ From<(Self::Rank, Self::Suit)>
+ Into<u8>
+ for<'a> TryFrom<&'a str>
{
type Rank: Copy + Eq + Hash + Ord + Send + Sync + 'static;
type Suit: Copy + Eq + Hash + Ord + Send + Sync + 'static;
fn rank(self) -> Self::Rank;
fn suit(self) -> Self::Suit;
}
pub trait PrettyCard: Card + From<Self::Card> {
type Card;
}
pub trait Deck: Clone + Default + Eq + IntoIterator<Item = Self::Card> {
type Card: Card;
fn as_slice(&self) -> &[Self::Card];
#[inline]
fn combinations<const N: usize>(&self) -> impl Iterator<Item = [Self::Card; N]> + '_ {
self.iter().copied().array_combinations::<N>()
}
fn draw(&mut self) -> Option<Self::Card>;
#[inline]
fn is_empty(&self) -> bool {
self.len() == 0
}
#[inline]
fn iter(&self) -> impl Iterator<Item = &Self::Card> {
self.as_slice().iter()
}
#[inline]
fn len(&self) -> usize {
self.as_slice().len()
}
fn new() -> Self;
fn remove(&mut self, card: &Self::Card) -> Option<Self::Card>;
fn shuffle(&mut self);
}