Skip to content

Commit

Permalink
Added Stardard52::card_from_string() (#37)
Browse files Browse the repository at this point in the history
  • Loading branch information
folkengine authored Jan 29, 2022
1 parent f094c12 commit 29e8ef3
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 4 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "cardpack"
description = "Generic Deck of Cards"
version = "0.4.12"
version = "0.4.13"
authors = ["folkengine <[email protected]>"]
repository = "https://github.com/ContractBridge/cardpack.rs.git"
homepage = "https://github.com/ContractBridge/cardpack.rs"
Expand Down
54 changes: 51 additions & 3 deletions src/cards/decks/standard52.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,9 +157,32 @@ impl Standard52 {
}

#[must_use]
pub fn card_from_index(card_str: &'static str) -> Card {
let rank = Rank::from_french_deck_index(Standard52::rank_str_from_index(card_str));
let suit = Suit::from_french_deck_index(Standard52::suit_char_from_index(card_str));
pub fn card_from_index(index: &'static str) -> Card {
let rank = Rank::from_french_deck_index(Standard52::rank_str_from_index(index));
let suit = Suit::from_french_deck_index(Standard52::suit_char_from_index(index));

if rank.is_blank() || suit.is_blank() {
Card::blank_card()
} else {
Card::new(rank, suit)
}
}

#[must_use]
#[allow(clippy::needless_pass_by_value)]
pub fn card_from_string(index: String) -> Card {
let char_vec: Vec<char> = index.chars().collect();

let mut rank = Rank::default();
let mut suit = Suit::default();

if let Some(r) = char_vec.get(0) {
rank = Rank::from_french_deck_char(*r);
}

if let Some(s) = char_vec.get(1) {
suit = Suit::from_french_deck_index(*s);
}

if rank.is_blank() || suit.is_blank() {
Card::blank_card()
Expand Down Expand Up @@ -411,6 +434,31 @@ mod standard52_tests {
assert_eq!(Card::blank_card(), Standard52::card_from_index(input));
}

#[rstest]
#[case(String::from("2S"), Card::from_index_strings(TWO, SPADES))]
#[case(String::from("2s"), Card::from_index_strings(TWO, SPADES))]
#[case(String::from("2♠"), Card::from_index_strings(TWO, SPADES))]
#[case(String::from("3S"), Card::from_index_strings(THREE, SPADES))]
#[case(String::from("3♠"), Card::from_index_strings(THREE, SPADES))]
#[case(String::from("4♠"), Card::from_index_strings(FOUR, SPADES))]
#[case(String::from("4S"), Card::from_index_strings(FOUR, SPADES))]
#[case(String::from("5♠"), Card::from_index_strings(FIVE, SPADES))]
#[case(String::from("5S"), Card::from_index_strings(FIVE, SPADES))]
fn card_from_string(#[case] input: String, #[case] expected: Card) {
assert_eq!(expected, Standard52::card_from_string(input));
}

#[rstest]
#[case(String::from("XX"))]
#[case(String::from("2X"))]
#[case(String::from("XS"))]
#[case(String::from(" "))]
#[case(String::from(" "))]
#[case(String::from(""))]
fn card_from_string__invalid_index(#[case] input: String) {
assert_eq!(Card::blank_card(), Standard52::card_from_string(input));
}

#[test]
fn sort_by_suit() {
let pile = Standard52::pile_from_index("2S 3S 9S TS QS JH Ac").unwrap();
Expand Down
47 changes: 47 additions & 0 deletions src/cards/rank.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,27 @@ impl Rank {
}
}

/// Returns a Rank entity based on its index string.
#[must_use]
pub fn from_french_deck_char(index: char) -> Rank {
match index {
'A' | 'a' => Rank::new(ACE),
'K' | 'k' => Rank::new(KING),
'Q' | 'q' => Rank::new(QUEEN),
'J' | 'j' => Rank::new(JACK),
'T' | 't' | '0' => Rank::new(TEN),
'9' => Rank::new(NINE),
'8' => Rank::new(EIGHT),
'7' => Rank::new(SEVEN),
'6' => Rank::new(SIX),
'5' => Rank::new(FIVE),
'4' => Rank::new(FOUR),
'3' => Rank::new(THREE),
'2' => Rank::new(TWO),
_ => Rank::new(BLANK_RANK),
}
}

#[must_use]
pub fn generate_canasta_ranks() -> Vec<Rank> {
Rank::from_array(&[
Expand Down Expand Up @@ -353,6 +374,32 @@ mod rank_tests {
assert_eq!(expected, Rank::from_array(&[KING, QUEEN]));
}

#[rstest]
#[case('A', Rank::new(ACE))]
#[case('a', Rank::new(ACE))]
#[case('K', Rank::new(KING))]
#[case('k', Rank::new(KING))]
#[case('Q', Rank::new(QUEEN))]
#[case('q', Rank::new(QUEEN))]
#[case('J', Rank::new(JACK))]
#[case('j', Rank::new(JACK))]
#[case('T', Rank::new(TEN))]
#[case('t', Rank::new(TEN))]
#[case('0', Rank::new(TEN))]
#[case('9', Rank::new(NINE))]
#[case('8', Rank::new(EIGHT))]
#[case('7', Rank::new(SEVEN))]
#[case('6', Rank::new(SIX))]
#[case('5', Rank::new(FIVE))]
#[case('4', Rank::new(FOUR))]
#[case('3', Rank::new(THREE))]
#[case('2', Rank::new(TWO))]
#[case('_', Rank::new(BLANK_RANK))]
#[case(' ', Rank::new(BLANK_RANK))]
fn from_french_deck_char(#[case] input: char, #[case] expected: Rank) {
assert_eq!(expected, Rank::from_french_deck_char(input));
}

#[rstest]
#[case("JB", Rank::new(BIG_JOKER))]
#[case("JL", Rank::new(LITTLE_JOKER))]
Expand Down

0 comments on commit 29e8ef3

Please sign in to comment.