use std::convert::TryFrom;
use std::fmt;
use std::fmt::{Debug, Display, Formatter};
use super::{rank_from_string, Rank, Suit, ACE, JACK, KING, QUEEN};
#[derive(Clone, Copy, Eq, PartialEq, Hash)]
pub struct Card {
pub suit: Suit,
pub rank: Rank,
}
impl Display for Card {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
let rank_string = match self.rank {
JACK => String::from("Jack"),
QUEEN => String::from("Queen"),
KING => String::from("King"),
ACE => String::from("Ace"),
_ => format!("{}", self.rank),
};
write!(f, "{} of {}s", rank_string, self.suit)
}
}
impl Debug for Card {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
let rank_string = match self.rank {
JACK => String::from("J"),
QUEEN => String::from("Q"),
KING => String::from("K"),
ACE => String::from("A"),
10 => String::from("T"),
_ => format!("{}", self.rank),
};
write!(f, "{}{:?}", rank_string, self.suit)
}
}
impl TryFrom<String> for Card {
type Error = String;
fn try_from(string: String) -> Result<Card, Self::Error> {
let string = string.trim();
if string.len() == 2 {
let suit = Suit::try_from(&string[1..2])?;
let rank = rank_from_string(&string[0..1])?;
Ok(Card { suit, rank })
} else {
let string: Vec<&str> = string.split(' ').collect();
let suit = Suit::try_from(*string.last().unwrap())?;
let rank = rank_from_string(string[0])?;
Ok(Card { suit, rank })
}
}
}
impl TryFrom<&str> for Card {
type Error = String;
fn try_from(string: &str) -> Result<Card, Self::Error> {
Card::try_from(string.to_string())
}
}