ionic_deckhandler/lib.rs
1use rand::{seq::SliceRandom, thread_rng};
2use std::cmp::Ordering;
3
4/// Provides a rank (value)
5///
6/// Examples:
7///
8/// ```
9/// use ionic_deckhandler::{Card, Suit, Rank};
10///
11/// let card = Card::new(Rank::Five, Suit::Hearts);
12/// let ucard_rank = Card::get_rank(&card) as usize;
13/// ```
14///
15/// ```
16/// use ionic_deckhandler::{Card, Suit, Rank};
17///
18/// let mut hand_arr = [
19/// Card::new(Rank::Five, Suit::Hearts),
20/// Card::new(Rank::Three, Suit::Hearts),
21/// Card::new(Rank::Two, Suit::Hearts),
22/// Card::new(Rank::Ace, Suit::Hearts),
23/// Card::new(Rank::Four, Suit::Hearts),
24/// ];
25/// ```
26#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
27pub enum Rank {
28 Ace,
29 Two,
30 Three,
31 Four,
32 Five,
33 Six,
34 Seven,
35 Eight,
36 Nine,
37 Ten,
38 Jack,
39 Queen,
40 King,
41}
42
43/// The total number of ranks within the deck of cards
44pub const CARD_RANK_COUNT: usize = 13;
45
46pub const ALL_RANKS: [Rank; CARD_RANK_COUNT] = [
47 Rank::Ace,
48 Rank::Two,
49 Rank::Three,
50 Rank::Four,
51 Rank::Five,
52 Rank::Six,
53 Rank::Seven,
54 Rank::Eight,
55 Rank::Nine,
56 Rank::Ten,
57 Rank::Jack,
58 Rank::Queen,
59 Rank::King,
60];
61
62/// Provides a card suit
63///
64/// Examples:
65///
66/// ```
67/// use ionic_deckhandler::{Card, Suit, Rank};
68///
69/// let card = Card::new(Rank::Five, Suit::Hearts);
70/// let ucard_suit = Card::get_suit(&card) as usize;
71/// ```
72///
73/// ```
74/// use ionic_deckhandler::{Card, Suit, Rank};
75///
76/// let mut hand_arr = [
77/// Card::new(Rank::Five, Suit::Hearts),
78/// Card::new(Rank::Three, Suit::Hearts),
79/// Card::new(Rank::Two, Suit::Hearts),
80/// Card::new(Rank::Ace, Suit::Hearts),
81/// Card::new(Rank::Four, Suit::Hearts),
82/// ];
83/// ```
84#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
85pub enum Suit {
86 Clubs,
87 Diamonds,
88 Hearts,
89 Spades,
90}
91
92pub const ALL_SUITS: [Suit; 4] = [Suit::Clubs, Suit::Diamonds, Suit::Hearts, Suit::Spades];
93
94/// A card containing a rank (card value) and a suit. A card may be compared
95/// by value against other cards.
96///
97/// Examples:
98///
99/// ```
100/// use ionic_deckhandler::{Card, Suit, Rank};
101///
102/// let mut hand_arr = [
103/// Card::new(Rank::Five, Suit::Hearts),
104/// Card::new(Rank::Three, Suit::Hearts),
105/// Card::new(Rank::Two, Suit::Hearts),
106/// Card::new(Rank::Ace, Suit::Hearts),
107/// Card::new(Rank::Four, Suit::Hearts),
108/// ];
109///
110/// hand_arr.sort();
111/// ```
112///
113#[derive(Debug, Copy, Clone)]
114pub struct Card {
115 pub rank: Rank,
116 pub suit: Suit,
117}
118
119impl Card {
120 pub fn new(rank: Rank, suit: Suit) -> Self {
121 Card { rank, suit }
122 }
123
124 pub fn get_deck() -> Vec<Self> {
125 let mut deck = Vec::new();
126 for suit in ALL_SUITS.iter() {
127 for rank in ALL_RANKS.iter() {
128 deck.push(Card::new(*rank, *suit));
129 }
130 }
131 deck
132 }
133
134 pub fn get_suit(&self) -> Suit {
135 self.suit
136 }
137
138 pub fn get_rank(&self) -> Rank {
139 self.rank
140 }
141}
142
143impl Ord for Card {
144 fn cmp(&self, other: &Self) -> Ordering {
145 self.rank.cmp(&other.rank)
146 }
147}
148
149impl PartialOrd for Card {
150 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
151 Some(self.cmp(other))
152 }
153}
154
155impl Eq for Card {}
156
157impl PartialEq for Card {
158 fn eq(&self, other: &Self) -> bool {
159 self.rank == other.rank
160 }
161}
162
163/// A deck may be shuffled and sorted
164///
165/// Example:
166///
167/// ```
168/// use ionic_deckhandler::{Card, Deck};
169///
170/// let mut deck = Card::get_deck();
171/// {
172/// let first_card = &deck[0];
173/// assert_eq!(
174/// format!("{:?}", first_card.get_suit()),
175/// String::from("Clubs")
176/// );
177/// }
178/// deck.shuffle_deck();
179///
180/// for card in deck.iter() {
181/// println!("{:?}", card);
182/// }
183/// deck.sort();
184/// for card in deck.iter() {
185/// println!("{:?}", card);
186/// }
187/// ```
188pub trait Deck {
189 fn shuffle_deck(&mut self);
190
191 fn take_from_top(&mut self) -> Option<Card>;
192
193 fn push_to_bottom(&mut self, card: Card);
194}
195
196impl Deck for Vec<Card> {
197 fn shuffle_deck(&mut self) {
198 self.shuffle(&mut thread_rng())
199 }
200
201 fn take_from_top(&mut self) -> Option<Card> {
202 self.pop()
203 }
204
205 fn push_to_bottom(&mut self, card: Card) {
206 let len = self.len();
207 self.insert(len, card);
208 }
209}