1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
/// A utility macro for creating a single card.
///
/// # Examples
///
/// Use [`card!`](crate::card!) with a capitalized rank and suit in order to get
/// a `const`-friendly card. The capitalization is because the names fill in as
/// enum variant names for [`Rank`] and [`Suit`]
///
/// ```
/// use poker::{Card, Rank, Suit, card};
/// const ACE_OF_SPADES: Card = card!(Ace, Spades);
/// assert_eq!(ACE_OF_SPADES, Card::new(Rank::Ace, Suit::Spades));
/// ```
///
/// Alternatively, you can separate the rank and suit with `of` for more
/// readability.
///
/// ```
/// use poker::{Card, Rank, Suit, card};
/// const ACE_OF_SPADES: Card = card!(Ace of Spades);
/// assert_eq!(ACE_OF_SPADES, Card::new(Rank::Ace, Suit::Spades));
/// ```
///
/// Finally, you can pass in a string expression, which will result in a call to
/// `parse()`. This, then, results in a [`Result`] and will fail if the rank is
/// not one of "23456789TJQKA" and the suit is not one of "chsd". This is
/// case-sensitive!
///
/// ```
/// use poker::{Card, Rank, Suit, card};
/// let ace_of_spades = card!("As").expect("couldn't parse card");
/// assert_eq!(ace_of_spades, Card::new(Rank::Ace, Suit::Spades));
/// ```
///
/// [`Rank`]: crate::Rank
/// [`Suit`]: crate::Suit
/// A utility macro for creating multiple cards.
///
/// # Examples
///
/// You can specify multiple cards by entering a comma-separated pair of
/// capitalized rank and suit, and with each pair being separated by a
/// semicolon. The reason for the capitalized names is because the macro inlines
/// these as enum variants of [`Rank`] and [`Suit`]. This is `const`-friendly
/// and results in an array type.
///
/// ```
/// use poker::{Card, Rank, Suit, cards};
///
/// const KING_AND_QUEEN: [Card; 2] = cards!(
/// King, Hearts;
/// Queen, Hearts; // trailing semicolon supported
/// );
/// assert_eq!(
/// KING_AND_QUEEN,
/// [
/// Card::new(Rank::King, Suit::Hearts),
/// Card::new(Rank::Queen, Suit::Hearts)
/// ]
/// );
/// ```
///
/// Secondly, you can specify multiple cards by separating rank and suit with
/// "of" and then separating each card with a comma. This may be more readable.
/// As in the previous example, this is `const`-friendly and returns an array.
///
/// ```
/// use poker::{Card, Rank, Suit, cards};
///
/// const KING_AND_QUEEN: [Card; 2] = cards!(
/// King of Hearts,
/// Queen of Hearts, // trailing comma supported
/// );
/// assert_eq!(
/// KING_AND_QUEEN,
/// [
/// Card::new(Rank::King, Suit::Hearts),
/// Card::new(Rank::Queen, Suit::Hearts)
/// ]
/// );
/// ```
///
/// As a third option, you can pass in a comma separated list of strings
/// representing cards, where each string is parsed individually. This returns
/// an iterator that will parse each string, yielding `Ok(Card)` on success, and
/// `Err(ParseCardError)` on failure. This macro calls [`Card::parse_to_iter`]
/// internally, so you can use [`try_collect`] on the iterator.
///
/// ```
/// use poker::{Card, Rank, Suit, cards};
///
/// // Collect into a `Vec<Card>` by using `collect::<Result<_, _>>()` on an iterator that
/// // yields `Result` types.
/// let king_and_queen: Vec<_> = cards!("Kh", "Qh")
/// .try_collect()
/// .expect("couldn't parse cards");
///
/// assert_eq!(
/// king_and_queen,
/// [
/// Card::new(Rank::King, Suit::Hearts),
/// Card::new(Rank::Queen, Suit::Hearts)
/// ]
/// );
/// ```
///
/// Finally, you can pass in a single string expression of cards, separated by
/// whitespace. This also returns an iterator over each card expression,
/// yielding a `Result`. You can also call [`try_collect`] in this case.
///
/// ```
/// use poker::{Card, Rank, Suit, cards};
///
/// let king_and_queen: Vec<_> = cards!("Kh Qh").try_collect().expect("couldn't parse cards");
///
/// assert_eq!(
/// king_and_queen,
/// [
/// Card::new(Rank::King, Suit::Hearts),
/// Card::new(Rank::Queen, Suit::Hearts)
/// ]
/// );
/// ```
///
/// [`Rank`]: crate::Rank
/// [`Suit`]: crate::Suit
/// [`Card::parse_to_iter`]: crate::Card::parse_to_iter
/// [`try_collect`]: crate::card::ParseToIter::try_collect
/// Use this macro to chain two or more slices of [`Card`] into a single boxed
/// slice of [`Card`]. This may be useful for bundling a hand and poker board
/// together for evaluation, as in Texas Holdem.
///
/// [`Card`]: crate::Card