diff --git a/src/card/impls.rs b/src/card/impls.rs index f24a294..ed5922a 100644 --- a/src/card/impls.rs +++ b/src/card/impls.rs @@ -7,29 +7,40 @@ ExactSizeIterator => Map> is not an ESI. But Range is an ESI. impl Rank { /// Generate an iterator over all ranks. - pub fn iter_all() -> impl ExactSizeIterator + Clone { - (0i32..13) - .map(|n| n as i64) - .map(|n| Rank::try_from(n).unwrap()) + pub fn iter_all() -> [Rank; 13] { + [ + Rank::Three, + Rank::Four, + Rank::Five, + Rank::Six, + Rank::Seven, + Rank::Eight, + Rank::Nine, + Rank::Ten, + Rank::Jack, + Rank::Queen, + Rank::King, + Rank::Ace, + Rank::Two, + ] } /// Generate an iterator over all cards within a rank, ordered by Suit. The /// cards are all default initialised w.r.t. deck (0). - pub fn cards(self) -> impl ExactSizeIterator + Clone { - let n = self as i32; - ((n * 4)..((n + 1) * 4)).map(|x| Card::from(x as i64)) + pub fn cards(self) -> [Card; 4] { + Suit::iter_all().map(move |suit| Card::make_playing_card(0, self, suit)) } } impl Suit { /// Generate an iterator over all suits. - pub fn iter_all() -> impl ExactSizeIterator + Clone { - (0i32..4).map(|n| Suit::try_from(n as i64).unwrap()) + pub fn iter_all() -> [Suit; 4] { + [Suit::Diamond, Suit::Club, Suit::Heart, Suit::Spade] } /// Generate an iterator over all cards within a suit, ordered by Rank. The /// cards are all default initialised in terms of deck (0). - pub fn cards(self) -> impl ExactSizeIterator + Clone { + pub fn cards(self) -> [Card; 13] { Rank::iter_all().map(move |rank| Card::make_playing_card(0, rank, self)) } } @@ -47,11 +58,12 @@ impl PlayingCard { /// Generate an iterator over all Playing Cards in the `nth` deck. By /// construction this is in ascending order. - pub fn iter_all(n: i64) -> impl ExactSizeIterator + Clone { - (0i32..52) - .map(|x| x as i64) - .map(move |x| x + (52 * n)) - .map(|x| PlayingCard::try_from(x).unwrap()) + pub fn iter_all(n: i64) -> [PlayingCard; 52] { + let mut cards: [PlayingCard; 52] = [PlayingCard::default(); 52]; + for i in 0..52 { + cards[i] = PlayingCard::try_from((i as i64) + (52 * n)).unwrap(); + } + cards } } diff --git a/src/card/tests.rs b/src/card/tests.rs index eb33a3f..82411ef 100644 --- a/src/card/tests.rs +++ b/src/card/tests.rs @@ -268,18 +268,17 @@ mod test_impls { use crate::{ card::{Card, PlayingCard, Rank, Suit}, - exactsizearr::ExactSizedArr, zipcartesian::ZipCartesianExt, }; #[test] fn rank() { - let ranks = Rank::iter_all().collect::>(); + let ranks = Rank::iter_all().into_iter().collect::>(); // TEST: Rank::iter_all produces all 13 unique ranks. assert_eq!(ranks.len(), 13); for rank in Rank::iter_all() { - let cards = rank.cards().collect::>(); + let cards = rank.cards().into_iter().collect::>(); assert_eq!(cards.len(), 4, "Expected 4 cards per rank"); for c in cards { // TEST: rank.cards() generates Playing Cards of the same rank @@ -304,12 +303,12 @@ mod test_impls { #[test] fn suit() { - let suits = Suit::iter_all().collect::>(); + let suits = Suit::iter_all().into_iter().collect::>(); // TEST: Suit::iter_all produces all 4 unique suits. assert_eq!(suits.len(), 4); for suit in Suit::iter_all() { - let cards = suit.cards().collect::>(); + let cards = suit.cards().into_iter().collect::>(); assert_eq!(cards.len(), 13, "Expected 13 cards per suit"); for c in cards { @@ -331,8 +330,9 @@ mod test_impls { #[test] fn playing_card() { for deck in 0..10 { - let playing_cards = - PlayingCard::iter_all(deck).collect::>(); + let playing_cards = PlayingCard::iter_all(deck) + .into_iter() + .collect::>(); // TEST: Expected 52 cards to be generated by PlayingCard::iter_all. assert_eq!( @@ -341,13 +341,7 @@ mod test_impls { "Expected 52 cards in a playing card deck" ); - for card in PlayingCard::iter_all(deck) - .into_array::<52>() - .unwrap_or_else(|_| { - unreachable!( - "Look at previous assertion; there must be 52 cards in the iterator." - ) - }) { + for card in PlayingCard::iter_all(deck) { // TEST: card.deck must match the input deck assert_eq!(card.deck, deck); let numeral = i64::from(card); @@ -414,7 +408,9 @@ mod test_impls { counter }; - for (rank, suit) in Rank::iter_all().zip_cartesian(Suit::iter_all()) + for (rank, suit) in Rank::iter_all() + .into_iter() + .zip_cartesian(Suit::iter_all().into_iter()) { // TEST: We expect `decks` instances of a (rank, suit) // combination in Card::iter_all(decks). diff --git a/src/modes/pair.rs b/src/modes/pair.rs index 4e95f81..fd4270b 100644 --- a/src/modes/pair.rs +++ b/src/modes/pair.rs @@ -108,14 +108,18 @@ mod tests { // TEST: Non pair tests. for (c1, c2) in Rank::iter_all() + .into_iter() // Generate tuples (r1, r2) where r1 != r2 .flat_map(|r1| { Rank::iter_all() + .into_iter() .filter(move |&r2| r2 != r1) .map(move |r2| (r1, r2)) }) // Generate all cards where their ranks differ - .flat_map(|(r1, r2)| r1.cards().zip_cartesian(r2.cards())) + .flat_map(|(r1, r2)| { + r1.cards().into_iter().zip_cartesian(r2.cards().into_iter()) + }) { // TEST: Two cards of differing rank cannot be a pair let pair = Pair::new(c1, c2); @@ -150,6 +154,7 @@ mod tests { ; PlayingCard::iter_all(0) .map(Card::PlayingCard) + .into_iter() // Flat Map every Playing Card (c1) into combinations (Card of same // rank as c1, c1) .flat_map(|c1| c1.rank().unwrap().cards().map(move |c2| (c1, c2))) diff --git a/src/modes/triple.rs b/src/modes/triple.rs index a45e895..3ec30c1 100644 --- a/src/modes/triple.rs +++ b/src/modes/triple.rs @@ -151,9 +151,9 @@ mod tests { } // Iterate over all pairs of cards with similar ranks - for (c1, c2) in - Rank::iter_all().flat_map(|r| r.cards().zip_cartesian(r.cards())) - { + for (c1, c2) in Rank::iter_all().into_iter().flat_map(|r| { + r.cards().into_iter().zip_cartesian(r.cards().into_iter()) + }) { let trip = Triple::new(c1, c2, joker); // TEST: Any two similar rank cards with 1 joker are a // Triple. @@ -189,12 +189,16 @@ mod tests { // Iterate over all pairs of cards with differing ranks for (c1, c2) in Rank::iter_all() + .into_iter() .flat_map(|r1| { Rank::iter_all() + .into_iter() .filter(move |&r2| r2 != r1) .map(move |r2| (r1, r2)) }) - .flat_map(|(r1, r2)| r1.cards().zip_cartesian(r2.cards())) + .flat_map(|(r1, r2)| { + r1.cards().into_iter().zip_cartesian(r2.cards().into_iter()) + }) { // TEST: Cannot make a triple out of 1 joker and two different rank // cards @@ -206,9 +210,13 @@ mod tests { } // Iterate over all triples of cards (regardless of rank) - for (c1, (c2, c3)) in PlayingCard::iter_all(0).zip_cartesian( - PlayingCard::iter_all(0).zip_cartesian(PlayingCard::iter_all(0)), - ) { + for (c1, (c2, c3)) in + PlayingCard::iter_all(0).into_iter().zip_cartesian( + PlayingCard::iter_all(0) + .into_iter() + .zip_cartesian(PlayingCard::iter_all(0).into_iter()), + ) + { let [c1, c2, c3] = [c1, c2, c3].map(Card::PlayingCard); let trip = Triple::new(c1, c2, c3);