card-core 0.1.1

Core playing-card types and abstractions
Documentation
//! Core interfaces for for playing cards.

use core::{fmt::Display, hash::Hash};
use itertools::Itertools as _;

/// The `Card` interface.
pub trait Card:
    Copy
    + Display
    + Eq
    + Hash
    + Ord
    + Send
    + Sync
    + 'static
    + From<(Self::Rank, Self::Suit)>
    + Into<u8>
    + for<'a> TryFrom<&'a str>
{
    /// The card's `Rank` type.
    type Rank: Copy + Eq + Hash + Ord + Send + Sync + 'static;
    /// The card's `Suit` type.
    type Suit: Copy + Eq + Hash + Ord + Send + Sync + 'static;

    /// Returns this card's rank.
    fn rank(self) -> Self::Rank;

    /// Returns this card's suit.
    fn suit(self) -> Self::Suit;
}

/// A card that supports ANSI-colored display.
pub trait PrettyCard: Card + From<Self::Card> {
    /// The backing type.
    type Card;
}

/// The `Deck` interface.
pub trait Deck: Clone + Default + Eq + IntoIterator<Item = Self::Card> {
    /// The type of `Card` that makes up the deck.
    type Card: Card;

    /// Returns the cards as a slice.
    fn as_slice(&self) -> &[Self::Card];

    /// Returns an iterator over every unordered combination of `N` cards.
    #[inline]
    fn combinations<const N: usize>(&self) -> impl Iterator<Item = [Self::Card; N]> + '_ {
        self.iter().copied().array_combinations::<N>()
    }

    /// Removes and returns the next card from the deck.
    fn draw(&mut self) -> Option<Self::Card>;

    /// Check if the deck is empty.
    #[inline]
    fn is_empty(&self) -> bool {
        self.len() == 0
    }

    /// Creates a non-consuming iterator.
    #[inline]
    fn iter(&self) -> impl Iterator<Item = &Self::Card> {
        self.as_slice().iter()
    }

    /// Returns the number of cards in the deck.
    #[inline]
    fn len(&self) -> usize {
        self.as_slice().len()
    }

    /// Create a new deck.
    fn new() -> Self;

    /// Attempt to remove a card from the deck. Returns true if the card was found.
    fn remove(&mut self, card: &Self::Card) -> Option<Self::Card>;

    /// Shuffle the deck.
    fn shuffle(&mut self);
}