From 9d2f737b5e29a54aa6a27503bc7ac0dc254c07bc Mon Sep 17 00:00:00 2001 From: MA Beaudet Date: Fri, 5 Nov 2021 15:33:12 +0100 Subject: [PATCH] fix: parsing a card now returns an option `card_from_str` is renamed to `parse_card` and now returns an `Option` instead of a `u32`. The function does not panic anymore. --- src/lib.rs | 72 ++++++++++++++++++++++++++++++++---------------------- 1 file changed, 43 insertions(+), 29 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index fa4fa09..83256ac 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -48,7 +48,7 @@ pub fn init_deck() -> Vec { deck } -/// Returns an integer based on the rank and the suit of a card. +/// Returns an option of integer based on the rank and the suit of a card. /// /// An integer is made up of four bytes. The high-order bytes are used to /// hold the rank bit pattern, whereas the low-order bytes hold @@ -73,40 +73,54 @@ pub fn init_deck() -> Vec { /// # Example /// /// ``` -/// use poker_eval::card_from_str; +/// use poker_eval::parse_card; /// /// assert_eq!( -/// card_from_str("Kd").to_be_bytes(), +/// parse_card("Kd").unwrap().to_be_bytes(), /// 0b00001000_00000000_01001011_00100101_u32.to_be_bytes() /// ); /// ``` -pub fn card_from_str(input: &str) -> u32 { +pub fn parse_card(input: &str) -> Option { let mut input = input.chars(); let (r, s) = (input.next(), input.next()); - let r = match r.unwrap() { - '2' => 0, - '3' => 1, - '4' => 2, - '5' => 3, - '6' => 4, - '7' => 5, - '8' => 6, - '9' => 7, - 'T' => 8, - 'J' => 9, - 'Q' => 10, - 'K' => 11, - 'A' => 12, - _ => panic!("{:?} is an invalid rank character", r), - }; - let s = match s.unwrap() { - 'c' => 0x8000, - 'd' => 0x4000, - 'h' => 0x2000, - 's' => 0x1000, - _ => panic!("{:?} is an invalid suit character", s), - }; - PRIMES[r] as u32 | (u32::try_from(r).unwrap() << 8) | s | (1 << (16 + r)) + match (r, s) { + (None, None) => None, + (None, Some(_)) => None, + (Some(_), None) => None, + (Some(r), Some(s)) => { + let r = match r { + '2' => Some(0), + '3' => Some(1), + '4' => Some(2), + '5' => Some(3), + '6' => Some(4), + '7' => Some(5), + '8' => Some(6), + '9' => Some(7), + 'T' => Some(8), + 'J' => Some(9), + 'Q' => Some(10), + 'K' => Some(11), + 'A' => Some(12), + _ => None, + }; + let s = match s { + 'c' => Some(0x8000), + 'd' => Some(0x4000), + 'h' => Some(0x2000), + 's' => Some(0x1000), + _ => None, + }; + match (r, s) { + (None, None) => None, + (None, Some(_)) => None, + (Some(_), None) => None, + (Some(r), Some(s)) => { + Some(PRIMES[r] as u32 | (u32::try_from(r).unwrap() << 8) | s | (1 << (16 + r))) + } + } + } + } } /// Performs a perfect hash lookup @@ -323,7 +337,7 @@ mod tests { #[test] fn card_from_string() { assert_eq!( - card_from_str("Kd"), + parse_card("Kd").unwrap(), 0b00001000_00000000_01001011_00100101_u32 ); } -- 2.20.1