use crate::color::Color;
use core::fmt::{self, Display};
use core::str::FromStr;
use crate::errors::{BASE_CARD_ERROR_CODE, ErrorCode};
#[repr(C)]
#[derive(Debug, Copy, Clone, serde::Serialize, serde::Deserialize, Eq, PartialEq)]
pub enum CardError {
InvalidCardError,
}
impl fmt::Display for CardError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
CardError::InvalidCardError => f.write_str("Invalid Card"),
}
}
}
impl ErrorCode for CardError {
fn error_code(&self) -> i32 {
BASE_CARD_ERROR_CODE
+ match *self {
CardError::InvalidCardError => 1,
}
}
}
#[repr(C)]
#[derive(
Clone, Copy, Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize, Ord, PartialOrd, Hash,
)]
pub enum StandardCardFace {
Ace,
Two,
Three,
Four,
Five,
Six,
Seven,
Eight,
Nine,
Ten,
Jack,
King,
Queen,
Joker,
}
impl Display for StandardCardFace {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"{}",
match self {
StandardCardFace::Ace => "ACE",
StandardCardFace::Two => "TWO",
StandardCardFace::Three => "THREE",
StandardCardFace::Four => "FOUR",
StandardCardFace::Five => "FIVE",
StandardCardFace::Six => "SIX",
StandardCardFace::Seven => "SEVEN",
StandardCardFace::Eight => "EIGHT",
StandardCardFace::Nine => "NINE",
StandardCardFace::Ten => "TEN",
StandardCardFace::Jack => "JACK",
StandardCardFace::King => "KING",
StandardCardFace::Queen => "Queen",
StandardCardFace::Joker => "JOKER",
}
)
}
}
impl FromStr for StandardCardFace {
type Err = CardError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"ACE" => Ok(StandardCardFace::Ace),
"TWO" => Ok(StandardCardFace::Two),
"THREE" => Ok(StandardCardFace::Three),
"FOUR" => Ok(StandardCardFace::Four),
"FIVE" => Ok(StandardCardFace::Five),
"SIX" => Ok(StandardCardFace::Six),
"SEVEN" => Ok(StandardCardFace::Seven),
"EIGHT" => Ok(StandardCardFace::Eight),
"NINE" => Ok(StandardCardFace::Nine),
"TEN" => Ok(StandardCardFace::Ten),
"JACK" => Ok(StandardCardFace::Jack),
"KING" => Ok(StandardCardFace::King),
"QUEEN" => Ok(StandardCardFace::Queen),
"JOKER" => Ok(StandardCardFace::Joker),
_ => Err(CardError::InvalidCardError),
}
}
}
#[repr(C)]
#[derive(
Clone, Copy, Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize, Ord, PartialOrd, Hash,
)]
pub enum StandardCard {
Clubs(StandardCardFace),
Diamonds(StandardCardFace),
Hearts(StandardCardFace),
Spades(StandardCardFace),
}
impl Display for StandardCard {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"{}",
match self {
StandardCard::Hearts(inner) => format!("HEARTS:{}", inner),
StandardCard::Spades(inner) => format!("SPADES:{}", inner),
StandardCard::Clubs(inner) => format!("CLUBS:{}", inner),
StandardCard::Diamonds(inner) => format!("DIAMONDS:{}", inner),
}
)
}
}
impl FromStr for StandardCard {
type Err = CardError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let txt = s.to_uppercase();
let mut txt = txt.split(':');
let card = txt.next().ok_or(CardError::InvalidCardError)?;
let face: StandardCardFace = txt.next().ok_or(CardError::InvalidCardError)?.parse()?;
match card {
"HEARTS" => Ok(StandardCard::Hearts(face)),
"SPADES" => Ok(StandardCard::Spades(face)),
"CLUBS" => Ok(StandardCard::Clubs(face)),
"DIAMONDS" => Ok(StandardCard::Diamonds(face)),
_ => Err(CardError::InvalidCardError),
}
}
}
impl StandardCard {
pub fn face(self) -> StandardCardFace {
StandardCardFace::from(self)
}
pub fn suite_string(self) -> &'static str {
match self {
StandardCard::Hearts(_) => "Hearts",
StandardCard::Clubs(_) => "Clubs",
StandardCard::Spades(_) => "Spades",
StandardCard::Diamonds(_) => "Diamonds",
}
}
pub fn face_to_string(self) -> String {
self.face().to_string()
}
pub fn color(self) -> Color {
match self {
StandardCard::Hearts(_) | StandardCard::Diamonds(_) => Color::Red,
StandardCard::Clubs(_) | StandardCard::Spades(_) => Color::Black,
}
}
pub fn eq_suite(self, card: StandardCard) -> bool {
match self {
StandardCard::Hearts(_) => matches!(card, StandardCard::Hearts(_)),
StandardCard::Spades(_) => matches!(card, StandardCard::Spades(_)),
StandardCard::Clubs(_) => matches!(card, StandardCard::Clubs(_)),
StandardCard::Diamonds(_) => matches!(card, StandardCard::Diamonds(_)),
}
}
}
impl StandardCardFace {
pub fn value(self) -> u8 {
u8::from(self)
}
}
impl From<StandardCard> for StandardCardFace {
fn from(card: StandardCard) -> StandardCardFace {
match card {
StandardCard::Hearts(inner) => inner,
StandardCard::Spades(inner) => inner,
StandardCard::Clubs(inner) => inner,
StandardCard::Diamonds(inner) => inner,
}
}
}
impl From<StandardCardFace> for u8 {
fn from(face: StandardCardFace) -> u8 {
match face {
StandardCardFace::Ace => 11,
StandardCardFace::Two => 2,
StandardCardFace::Three => 3,
StandardCardFace::Four => 4,
StandardCardFace::Five => 5,
StandardCardFace::Six => 6,
StandardCardFace::Seven => 7,
StandardCardFace::Eight => 8,
StandardCardFace::Nine => 9,
_ => 10,
}
}
}
impl From<StandardCard> for u8 {
fn from(card: StandardCard) -> u8 {
u8::from(StandardCardFace::from(card))
}
}