espada 0.3.1

Texas Hold'em poker odds evaluator
Documentation
use std::fmt::{Display, Formatter};
use std::str::FromStr;

#[derive(Debug, PartialEq, Eq, Hash, PartialOrd, Ord, Clone, Copy)]
pub enum Suit {
    Spade,
    Heart,
    Diamond,
    Club,
}

impl Display for Suit {
    fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
        let c: char = self.into();

        c.to_string().fmt(f)
    }
}

impl TryFrom<&char> for Suit {
    type Error = ();

    fn try_from(c: &char) -> Result<Self, Self::Error> {
        match c {
            's' => Ok(Suit::Spade),
            'h' => Ok(Suit::Heart),
            'd' => Ok(Suit::Diamond),
            'c' => Ok(Suit::Club),
            _ => Err(()),
        }
    }
}

impl TryFrom<char> for Suit {
    type Error = ();

    fn try_from(c: char) -> Result<Self, Self::Error> {
        (&c).try_into()
    }
}

impl FromStr for Suit {
    type Err = ();

    fn from_str(value: &str) -> Result<Self, Self::Err> {
        if let Some(c) = value.chars().nth(0) {
            c.try_into()
        } else {
            Err(())
        }
    }
}

impl From<&Suit> for u8 {
    fn from(suit: &Suit) -> Self {
        match suit {
            Suit::Spade => 0,
            Suit::Heart => 1,
            Suit::Diamond => 2,
            Suit::Club => 3,
        }
    }
}

impl From<Suit> for u8 {
    fn from(suit: Suit) -> Self {
        u8::from(&suit)
    }
}

impl From<&Suit> for char {
    fn from(value: &Suit) -> Self {
        match value {
            Suit::Spade => 's',
            Suit::Heart => 'h',
            Suit::Diamond => 'd',
            Suit::Club => 'c',
        }
    }
}

impl From<Suit> for char {
    fn from(value: Suit) -> Self {
        char::from(&value)
    }
}

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

    mod display {
        use super::*;

        #[test]
        fn it_parses_into_s() {
            assert_eq!(Suit::Spade.to_string(), "s");
        }

        #[test]
        fn it_parses_into_k() {
            assert_eq!(Suit::Heart.to_string(), "h");
        }

        #[test]
        fn it_parses_into_q() {
            assert_eq!(Suit::Diamond.to_string(), "d");
        }

        #[test]
        fn it_parses_into_j() {
            assert_eq!(Suit::Club.to_string(), "c");
        }
    }

    mod try_from_char {
        use super::*;

        #[test]
        fn it_parses_into_spade() {
            let result: Result<Suit, ()> = 's'.try_into();

            assert_eq!(result.unwrap(), Suit::Spade);
        }

        #[test]
        fn it_parses_into_heart() {
            let result: Result<Suit, ()> = 'h'.try_into();

            assert_eq!(result.unwrap(), Suit::Heart);
        }

        #[test]
        fn it_parses_into_diamond() {
            let result: Result<Suit, ()> = 'd'.try_into();

            assert_eq!(result.unwrap(), Suit::Diamond);
        }

        #[test]
        fn it_parses_into_club() {
            let result: Result<Suit, ()> = 'c'.try_into();

            assert_eq!(result.unwrap(), Suit::Club);
        }

        #[test]
        fn it_failes_parsing() {
            let result: Result<Suit, ()> = 'X'.try_into();

            assert_eq!(result.is_err(), true);
        }
    }

    mod from_str {
        use super::*;

        #[test]
        fn it_parses_into_spade() {
            assert_eq!("s".parse::<Suit>().unwrap(), Suit::Spade);
        }

        #[test]
        fn it_parses_into_heart() {
            assert_eq!("h".parse::<Suit>().unwrap(), Suit::Heart);
        }

        #[test]
        fn it_parses_into_diamond() {
            assert_eq!("d".parse::<Suit>().unwrap(), Suit::Diamond);
        }

        #[test]
        fn it_parses_into_club() {
            assert_eq!("c".parse::<Suit>().unwrap(), Suit::Club);
        }

        #[test]
        fn it_failes_parsing() {
            assert_eq!("X".parse::<Suit>().is_err(), true);
        }
    }

    mod u8_from_rank {
        use super::*;

        #[test]
        fn it_parses_into_0() {
            let num: u8 = Suit::Spade.into();

            assert_eq!(num, 0);
        }

        #[test]
        fn it_parses_into_1() {
            let num: u8 = Suit::Heart.into();

            assert_eq!(num, 1);
        }

        #[test]
        fn it_parses_into_2() {
            let num: u8 = Suit::Diamond.into();

            assert_eq!(num, 2);
        }

        #[test]
        fn it_parses_into_3() {
            let num: u8 = Suit::Club.into();

            assert_eq!(num, 3);
        }
    }

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

        #[test]
        fn it_parses_into_s() {
            let c: char = Suit::Spade.into();

            assert_eq!(c, 's');
        }

        #[test]
        fn it_parses_into_h() {
            let c: char = Suit::Heart.into();

            assert_eq!(c, 'h');
        }

        #[test]
        fn it_parses_into_d() {
            let c: char = Suit::Diamond.into();

            assert_eq!(c, 'd');
        }

        #[test]
        fn it_parses_into_c() {
            let c: char = Suit::Club.into();

            assert_eq!(c, 'c');
        }
    }
}