1use crate::color::Color;
26use core::fmt::{self, Display};
27use core::str::FromStr;
28
29use crate::errors::{BASE_CARD_ERROR_CODE, ErrorCode};
30
31#[repr(C)]
32#[derive(Debug, Copy, Clone, serde::Serialize, serde::Deserialize, Eq, PartialEq)]
33pub enum CardError {
35 InvalidCardError,
38}
39
40impl fmt::Display for CardError {
41 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
42 match *self {
43 CardError::InvalidCardError => f.write_str("Invalid Card"),
44 }
45 }
46}
47
48impl ErrorCode for CardError {
49 fn error_code(&self) -> i32 {
50 BASE_CARD_ERROR_CODE
51 + match *self {
52 CardError::InvalidCardError => 1,
53 }
54 }
55}
56
57#[repr(C)]
59#[derive(
60 Clone, Copy, Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize, Ord, PartialOrd, Hash,
61)]
62pub enum StandardCardFace {
63 Ace,
65 Two,
67 Three,
69 Four,
71 Five,
73 Six,
75 Seven,
77 Eight,
79 Nine,
81 Ten,
83 Jack,
85 King,
87 Queen,
89 Joker,
91}
92
93impl Display for StandardCardFace {
94 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
95 write!(
96 f,
97 "{}",
98 match self {
99 StandardCardFace::Ace => "ACE",
100 StandardCardFace::Two => "TWO",
101 StandardCardFace::Three => "THREE",
102 StandardCardFace::Four => "FOUR",
103 StandardCardFace::Five => "FIVE",
104 StandardCardFace::Six => "SIX",
105 StandardCardFace::Seven => "SEVEN",
106 StandardCardFace::Eight => "EIGHT",
107 StandardCardFace::Nine => "NINE",
108 StandardCardFace::Ten => "TEN",
109 StandardCardFace::Jack => "JACK",
110 StandardCardFace::King => "KING",
111 StandardCardFace::Queen => "Queen",
112 StandardCardFace::Joker => "JOKER",
113 }
114 )
115 }
116}
117impl FromStr for StandardCardFace {
118 type Err = CardError;
119
120 fn from_str(s: &str) -> Result<Self, Self::Err> {
121 match s {
122 "ACE" => Ok(StandardCardFace::Ace),
123 "TWO" => Ok(StandardCardFace::Two),
124 "THREE" => Ok(StandardCardFace::Three),
125 "FOUR" => Ok(StandardCardFace::Four),
126 "FIVE" => Ok(StandardCardFace::Five),
127 "SIX" => Ok(StandardCardFace::Six),
128 "SEVEN" => Ok(StandardCardFace::Seven),
129 "EIGHT" => Ok(StandardCardFace::Eight),
130 "NINE" => Ok(StandardCardFace::Nine),
131 "TEN" => Ok(StandardCardFace::Ten),
132 "JACK" => Ok(StandardCardFace::Jack),
133 "KING" => Ok(StandardCardFace::King),
134 "QUEEN" => Ok(StandardCardFace::Queen),
135 "JOKER" => Ok(StandardCardFace::Joker),
136 _ => Err(CardError::InvalidCardError),
137 }
138 }
139}
140
141#[repr(C)]
143#[derive(
144 Clone, Copy, Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize, Ord, PartialOrd, Hash,
145)]
146pub enum StandardCard {
147 Clubs(StandardCardFace),
149 Diamonds(StandardCardFace),
151 Hearts(StandardCardFace),
153 Spades(StandardCardFace),
155}
156
157impl Display for StandardCard {
158 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
159 write!(
160 f,
161 "{}",
162 match self {
163 StandardCard::Hearts(inner) => format!("HEARTS:{}", inner),
164 StandardCard::Spades(inner) => format!("SPADES:{}", inner),
165 StandardCard::Clubs(inner) => format!("CLUBS:{}", inner),
166 StandardCard::Diamonds(inner) => format!("DIAMONDS:{}", inner),
167 }
168 )
169 }
170}
171
172impl FromStr for StandardCard {
173 type Err = CardError;
174 fn from_str(s: &str) -> Result<Self, Self::Err> {
175 let txt = s.to_uppercase();
176 let mut txt = txt.split(':');
177 let card = txt.next().ok_or(CardError::InvalidCardError)?;
178 let face: StandardCardFace = txt.next().ok_or(CardError::InvalidCardError)?.parse()?;
179 match card {
180 "HEARTS" => Ok(StandardCard::Hearts(face)),
181 "SPADES" => Ok(StandardCard::Spades(face)),
182 "CLUBS" => Ok(StandardCard::Clubs(face)),
183 "DIAMONDS" => Ok(StandardCard::Diamonds(face)),
184 _ => Err(CardError::InvalidCardError),
185 }
186 }
187}
188
189impl StandardCard {
190 pub fn face(self) -> StandardCardFace {
192 StandardCardFace::from(self)
193 }
194 pub fn suite_string(self) -> &'static str {
196 match self {
197 StandardCard::Hearts(_) => "Hearts",
198 StandardCard::Clubs(_) => "Clubs",
199 StandardCard::Spades(_) => "Spades",
200 StandardCard::Diamonds(_) => "Diamonds",
201 }
202 }
203 pub fn face_to_string(self) -> String {
205 self.face().to_string()
206 }
207 pub fn color(self) -> Color {
209 match self {
210 StandardCard::Hearts(_) | StandardCard::Diamonds(_) => Color::Red,
211 StandardCard::Clubs(_) | StandardCard::Spades(_) => Color::Black,
212 }
213 }
214 pub fn eq_suite(self, card: StandardCard) -> bool {
216 match self {
217 StandardCard::Hearts(_) => matches!(card, StandardCard::Hearts(_)),
218 StandardCard::Spades(_) => matches!(card, StandardCard::Spades(_)),
219 StandardCard::Clubs(_) => matches!(card, StandardCard::Clubs(_)),
220 StandardCard::Diamonds(_) => matches!(card, StandardCard::Diamonds(_)),
221 }
222 }
223}
224
225impl StandardCardFace {
226 pub fn value(self) -> u8 {
229 u8::from(self)
230 }
231}
232
233impl From<StandardCard> for StandardCardFace {
234 fn from(card: StandardCard) -> StandardCardFace {
235 match card {
236 StandardCard::Hearts(inner) => inner,
237 StandardCard::Spades(inner) => inner,
238 StandardCard::Clubs(inner) => inner,
239 StandardCard::Diamonds(inner) => inner,
240 }
241 }
242}
243
244impl From<StandardCardFace> for u8 {
245 fn from(face: StandardCardFace) -> u8 {
246 match face {
247 StandardCardFace::Ace => 11,
248 StandardCardFace::Two => 2,
249 StandardCardFace::Three => 3,
250 StandardCardFace::Four => 4,
251 StandardCardFace::Five => 5,
252 StandardCardFace::Six => 6,
253 StandardCardFace::Seven => 7,
254 StandardCardFace::Eight => 8,
255 StandardCardFace::Nine => 9,
256 _ => 10,
257 }
258 }
259}
260
261impl From<StandardCard> for u8 {
262 fn from(card: StandardCard) -> u8 {
263 u8::from(StandardCardFace::from(card))
264 }
265}