1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
use super::{Rank, Suit};
use serde::{Deserialize, Serialize};

#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
#[serde(tag = "type")]
#[serde(rename_all = "lowercase")]
pub enum Card {
    Joker { deck_id: u8 },
    Standard { deck_id: u8, rank: Rank, suit: Suit },
}

impl Card {
    pub fn get_rank(self) -> Option<Rank> {
        match self {
            Card::Standard { rank, .. } => Some(rank),
            _ => None,
        }
    }

    pub fn get_suit(self) -> Option<Suit> {
        match self {
            Card::Standard { suit, .. } => Some(suit),
            _ => None,
        }
    }
}


#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub struct PlayedCard {
    rank: Rank,
    suit: Suit,
    is_joker: bool,
}

impl PlayedCard {
    pub fn new(rank: Rank, suit: Suit, is_joker: bool) -> PlayedCard {
        PlayedCard {
            is_joker,
            rank,
            suit,
        }
    }

    pub fn get_rank(self) -> Rank {
        self.rank
    }

    pub fn get_suit(self) -> Suit {
        self.suit
    }

    pub fn get_is_joker(self) -> bool {
        self.is_joker
    }

    pub fn to_card(self) -> Card {
        if self.is_joker {
            Card::Joker { deck_id: 0 }
        } else {
            Card::Standard {
                deck_id: 0,
                rank: self.rank,
                suit: self.suit,
            }
        }
    }
}

#[cfg(test)]
mod tests {
    use super::super::*;

    #[test]
    fn card_has_rank_and_suit() {
        let ace_of_spades = Card::Standard {
            deck_id: 0,
            rank: Rank::Ace,
            suit: Suit::Spades,
        };

        assert_eq!(ace_of_spades.get_rank().unwrap(), Rank::Ace);
        assert_eq!(ace_of_spades.get_suit().unwrap(), Suit::Spades);
    }

    #[test]
    fn played_joker_has_rank_and_suit() {
        let joker_ace_of_spades = PlayedCard::new(Rank::Ace, Suit::Spades, true);

        assert_eq!(joker_ace_of_spades.get_rank(), Rank::Ace);
        assert_eq!(joker_ace_of_spades.get_suit(), Suit::Spades);
    }

    #[test]
    fn played_card_to_card() {
        let ace_of_spades = Card::Standard {
            deck_id: 0,
            rank: Rank::Ace,
            suit: Suit::Spades,
        };
        let joker = Card::Joker { deck_id: 0 };

        let played_ace_of_spades = PlayedCard::new(Rank::Ace, Suit::Spades, false);
        let played_joker = PlayedCard::new(Rank::Ace, Suit::Spades, true);

        assert_eq!(played_ace_of_spades.to_card(), ace_of_spades);
        assert_eq!(played_joker.to_card(), joker);
    }
}