wordletron 0.1.3

A solver for Wordle
Documentation
use custom_derive::custom_derive;
use newtype_derive::*;

use std::array::TryFromSliceError;
use std::fmt;
use std::iter;

use super::N;

#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Debug)]
pub enum ClueColor {
    Green,
    Yellow,
    Black,
}
pub use ClueColor::*;

impl From<&ClueColor> for &'static str {
    fn from(c: &ClueColor) -> Self {
        match c {
            Green => "🟩",
            Yellow => "🟨",
            Black => "⬛️",
        }
    }
}

custom_derive! {
    #[derive(NewtypeFrom, NewtypeIndex(usize), NewtypeIndexMut(usize), PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Debug)]
    pub struct Clue(pub [ClueColor; N]);
}

impl Clue {
    pub fn iter(&self) -> std::slice::Iter<ClueColor> {
        self.0.iter()
    }

    pub fn iter_mut(&mut self) -> std::slice::IterMut<ClueColor> {
        self.0.iter_mut()
    }
}

impl From<&Clue> for String {
    fn from(clue: &Clue) -> Self {
        clue.0
            .iter()
            .map(|c| {
                let s: &str = c.into();
                s
            })
            .collect()
    }
}

impl TryFrom<char> for ClueColor {
    type Error = &'static str;

    fn try_from(c: char) -> Result<Self, Self::Error> {
        match c.to_lowercase().next() {
            Some('g') => Ok(Green),
            Some('y') => Ok(Yellow),
            Some('b') => Ok(Black),
            _ => Err("invalid color"),
        }
    }
}

impl TryFrom<&[ClueColor]> for Clue {
    type Error = TryFromSliceError;

    fn try_from(s: &[ClueColor]) -> Result<Self, Self::Error> {
        Ok(Clue(s.try_into()?))
    }
}

impl fmt::Display for Clue {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let s: String = self.into();
        write!(f, "{}", s)
    }
}

impl iter::IntoIterator for Clue {
    type Item = ClueColor;
    type IntoIter = std::array::IntoIter<Self::Item, N>;
    fn into_iter(self) -> Self::IntoIter {
        self.0.into_iter()
    }
}