use std::{error::Error, fmt};
use itertools::Itertools;
use crate::card::Card;
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum ParseCardError {
InvalidLength {
original_input: String,
},
InvalidRank {
original_input: String,
incorrect_char: char,
},
InvalidSuit {
original_input: String,
incorrect_char: char,
},
}
impl fmt::Display for ParseCardError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Self::InvalidLength { original_input } => write!(
f,
"Error parsing input '{}' as a Card: Found input of length {}, expected 2",
original_input,
original_input.len()
),
Self::InvalidRank {
original_input,
incorrect_char,
} => write!(
f,
"Error parsing input '{}' as a Card: Invalid rank character '{}', expected one of \
[23456789TJQKA]",
original_input, incorrect_char
),
Self::InvalidSuit {
original_input,
incorrect_char,
} => write!(
f,
"Error parsing input '{}' as a Card: Invalid suit character '{}', expected one of \
[chsd]",
original_input, incorrect_char
),
}
}
}
impl Error for ParseCardError {}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum EvalError {
CardsNotUnique(Vec<Card>),
InvalidHandSize(usize),
}
impl fmt::Display for EvalError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Self::CardsNotUnique(cards) => {
let dups: String = cards
.iter()
.counts()
.into_iter()
.filter_map(|(card, count)| {
if count > 1 {
Some(card.rank_suit_string())
} else {
None
}
})
.collect::<Vec<_>>()
.join(" ");
write!(
f,
"Cannot evaluate a poker hand with a set of cards that are not unique. Cards \
duplicated at least once: {}",
dups
)
}
Self::InvalidHandSize(size) => write!(
f,
"Cannot evaluate a poker hand with a set of less than 5 cards. Number of cards \
received: {}",
size
),
}
}
}
impl Error for EvalError {}