use std::str::FromStr;
-use crate::{constants::PRIMES, MyError, Rules};
+use crate::{constants::PRIMES, errors::ParseCardError, Rules};
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
-#[derive(Debug, Default, Clone, Hash)]
+#[derive(Debug, Default, Clone, Hash, PartialEq)]
pub struct Cards(Vec<Card>);
impl Cards {
}
impl FromStr for Cards {
- type Err = MyError;
+ type Err = ParseCardError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
- Ok(Self(
- s.trim()
- .split_whitespace()
- .map(|c| Card::from_str(c).expect("Could not parse card from string"))
- .collect::<Vec<_>>(),
- ))
+ let mut cards = Cards::new();
+ for c in s.trim().split_whitespace() {
+ let c = Card::from_str(c)?;
+ cards.0.push(c);
+ }
+ Ok(cards)
}
}
&self.0
}
- pub fn deal_with_rules(&mut self, rules: &Rules) -> Result<Cards, MyError> {
+ pub fn deal_with_rules(&mut self, rules: &Rules) -> Result<Cards, ParseCardError> {
let v = match rules {
Rules::Classic => self.deal(5)?,
&mut self,
rules: &Rules,
player_nb: usize,
- ) -> Result<Vec<Cards>, MyError> {
+ ) -> Result<Vec<Cards>, ParseCardError> {
(0..player_nb)
.into_iter()
.map(|_| Ok(self.deal_with_rules(rules)?))
.collect()
}
- pub fn deal(&mut self, n: usize) -> Result<Cards, MyError> {
+ pub fn deal(&mut self, n: usize) -> Result<Cards, ParseCardError> {
if self.0 .0.len() < n {
- Err(MyError::IndexError)
+ Err(ParseCardError::Index)
} else {
Ok(Cards(self.0 .0.split_off(self.0 .0.len() - n)))
}
}
}
-/// ```
-/// use poker_eval::{Card};
-/// use std::str::FromStr;
-///
-/// assert_eq!(
-/// Card::from_str("Kd").unwrap().get(),
-/// 0b00001000_00000000_01001011_00100101_u32
-/// );
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Debug, Clone, Copy, Hash)]
#[repr(transparent)]
}
}
- /// ```
- /// use poker_eval::{Card};
- /// use std::str::FromStr;
- ///
- /// let card = Card::from_str("Kd").unwrap();
- /// assert_eq!(card.rank(), 'K');
- /// ```
pub fn rank(&self) -> char {
match (self.0 >> 8) & 0xF {
0 => '2',
}
impl TryFrom<u32> for Card {
- type Error = MyError;
+ type Error = ParseCardError;
fn try_from(value: u32) -> Result<Self, Self::Error> {
let _ = match (value >> 8) & 0xF {
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 => Ok(()),
- _ => Err(MyError::InvalidRank),
+ _ => Err(ParseCardError::U32),
};
let _ = match (value >> 12) & 0xF {
0b1000 | 0b0100 | 0b0010 | 0b0001 => Ok(()),
- _ => Err(MyError::InvalidSuit),
+ _ => Err(ParseCardError::U32),
};
Ok(Self(value))
}
}
-/// ```
-/// use poker_eval::{Card};
-/// use std::str::FromStr;
-///
-/// let card = Card::from_str("Kd").unwrap();
-/// let other = Card::from_str("Qd").unwrap();
-/// let other2 = Card::from_str("Ks").unwrap();
-/// assert!(card > other);
-/// assert!(card <= other2);
-/// ```
impl PartialOrd for Card {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
((self.0 >> 8) & 0xF).partial_cmp(&((other.0 >> 8) & 0xF))
}
}
-/// ```
-/// use poker_eval::{Card};
-/// use std::str::FromStr;
-///
-/// let card = Card::from_str("Kd").unwrap();
-/// let other = Card::from_str("Ks").unwrap();
-/// assert!(card == other);
-/// ```
impl PartialEq for Card {
fn eq(&self, other: &Self) -> bool {
(self.0 >> 8) & 0xF == (other.0 >> 8) & 0xF
impl Eq for Card {}
impl FromStr for Card {
- type Err = MyError;
+ type Err = ParseCardError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let mut input = s.chars();
let (r, s) = (input.next(), input.next());
match (r, s) {
- (None, None) => Err(MyError::InvalidLength),
- (None, Some(_)) => Err(MyError::InvalidLength),
- (Some(_), None) => Err(MyError::InvalidLength),
+ (None, None) => Err(ParseCardError::String),
+ (None, Some(_)) => Err(ParseCardError::String),
+ (Some(_), None) => Err(ParseCardError::String),
(Some(r), Some(s)) => {
let r = match r {
'2' => Some(0),
_ => None,
};
match (r, s) {
- (None, None) => Err(MyError::InvalidLength),
- (None, Some(_)) => Err(MyError::InvalidRank),
- (Some(_), None) => Err(MyError::InvalidSuit),
+ (None, None) => Err(ParseCardError::Chars),
+ (None, Some(_)) => Err(ParseCardError::Rank),
+ (Some(_), None) => Err(ParseCardError::Suit),
(Some(r), Some(s)) => Ok(Self(
PRIMES[r as usize] as u32 | (r << 8) | s | (1 << (16 + r)),
)),
}
}
-/// ```
-/// use poker_eval::{Card};
-/// use std::str::FromStr;
-///
-/// let card = Card::from_str("Kd").unwrap();
-/// assert_eq!(card.to_string(), "Kd");
-/// ```
impl std::fmt::Display for Card {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}{}", self.rank(), self.suit())
assert_sync::<Cards>();
assert_sync::<Deck>();
}
+
+#[test]
+fn test_fromstr() {
+ assert!(Cards::from_str("7s 3v").is_err());
+ assert_eq!(Cards::from_str("7s 3v").unwrap_err(), ParseCardError::Suit);
+ assert_eq!(Cards::from_str("7s fv").unwrap_err(), ParseCardError::Chars);
+ assert_eq!(Cards::from_str("7s fd").unwrap_err(), ParseCardError::Rank);
+ assert!(Cards::from_str("7s 3d").is_ok());
+ assert_eq!(
+ Cards::from_str("7s 3d").unwrap(),
+ Cards(vec![
+ Card::from_str("7s").unwrap(),
+ Card::from_str("3d").unwrap()
+ ])
+ );
+ assert!(Card::from_str("3v").is_err());
+ assert_eq!(Card::from_str("3v").unwrap_err(), ParseCardError::Suit);
+ assert_eq!(Card::from_str("fv").unwrap_err(), ParseCardError::Chars);
+ assert_eq!(Card::from_str("fd").unwrap_err(), ParseCardError::Rank);
+ assert_eq!(
+ *Card::from_str("Kd").unwrap().as_ref(),
+ 0b00001000_00000000_01001011_00100101_u32
+ );
+}
+
+#[test]
+fn test_tostr() {
+ let card = Card::from_str("Kd").unwrap();
+ assert_eq!(card.to_string(), "Kd");
+}