use std::convert::TryFrom;
use std::fmt::{Display, Error, Formatter, Debug};
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash, Ord, PartialOrd)]
pub enum ConsoleColor {
Black = 0,
DarkBlue = 1,
DarkGreen = 2,
DarkCyan = 3,
DarkRed = 4,
DarkMagenta = 5,
DarkYellow = 6,
Gray = 7,
DarkGray = 8,
Blue = 9,
Green = 10,
Cyan = 11,
Red = 12,
Magenta = 13,
Yellow = 14,
White = 15,
}
impl ConsoleColor {
#[inline]
pub fn as_foreground_color(&self) -> u16 {
*self as u16
}
#[inline]
pub fn as_background_color(&self) -> u16 {
(*self as u16) << 4
}
}
pub struct ParseColorError(u16);
impl Debug for ParseColorError{
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "Invalid color value: {}", self.0)
}
}
impl TryFrom<u16> for ConsoleColor{
type Error = ParseColorError;
fn try_from(value: u16) -> Result<Self, Self::Error> {
match value {
0 => Ok(ConsoleColor::Black),
1 => Ok(ConsoleColor::DarkBlue),
2 => Ok(ConsoleColor::DarkGreen),
3 => Ok(ConsoleColor::DarkCyan),
4 => Ok(ConsoleColor::DarkRed),
5 => Ok(ConsoleColor::DarkMagenta),
6 => Ok(ConsoleColor::DarkYellow),
7 => Ok(ConsoleColor::Gray),
8 => Ok(ConsoleColor::DarkGray),
9 => Ok(ConsoleColor::Blue),
10 => Ok(ConsoleColor::Green),
11 => Ok(ConsoleColor::Cyan),
12 => Ok(ConsoleColor::Red),
13 => Ok(ConsoleColor::Magenta),
14 => Ok(ConsoleColor::Yellow),
15 => Ok(ConsoleColor::White),
_ => Err(ParseColorError(value))
}
}
}
impl Into<u16> for ConsoleColor {
#[inline]
fn into(self) -> u16 {
self.as_foreground_color()
}
}
impl Display for ConsoleColor{
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
match self {
ConsoleColor::Black => { f.write_str("ConsoleColor::Black") },
ConsoleColor::DarkBlue => { f.write_str("ConsoleColor::DarkBlue") },
ConsoleColor::DarkGreen => { f.write_str("ConsoleColor::DarkGreen") },
ConsoleColor::DarkCyan => { f.write_str("ConsoleColor::DarkCyan") },
ConsoleColor::DarkRed => { f.write_str("ConsoleColor::DarkRed") },
ConsoleColor::DarkMagenta => { f.write_str("ConsoleColor::DarkMagenta") },
ConsoleColor::DarkYellow => { f.write_str("ConsoleColor::DarkYellow") },
ConsoleColor::Gray => { f.write_str("ConsoleColor::Gray") },
ConsoleColor::DarkGray => { f.write_str("ConsoleColor::DarkGray") },
ConsoleColor::Blue => { f.write_str("ConsoleColor::Blue") },
ConsoleColor::Green => { f.write_str("ConsoleColor::Green") },
ConsoleColor::Cyan => { f.write_str("ConsoleColor::Cyan") },
ConsoleColor::Red => { f.write_str("ConsoleColor::Red") },
ConsoleColor::Magenta => { f.write_str("ConsoleColor::Magenta") },
ConsoleColor::Yellow => { f.write_str("ConsoleColor::Yellow") },
ConsoleColor::White => { f.write_str("ConsoleColor::White") },
}
}
}
#[cfg(test)]
mod tests{
use super::ConsoleColor;
use crate::console::ConsoleTextAttribute;
use std::convert::TryFrom;
#[test]
fn as_foreground_test(){
let color = ConsoleColor::DarkRed;
assert_eq!(ConsoleTextAttribute::FOREGROUND_RED, color.as_foreground_color());
}
#[test]
fn as_background_test(){
let color = ConsoleColor::DarkRed;
assert_eq!(ConsoleTextAttribute::BACKGROUND_RED, color.as_background_color());
}
#[test]
fn try_from_test1(){
let color = ConsoleColor::try_from(4).ok();
assert!(color.is_some());
assert_eq!(ConsoleColor::DarkRed, color.unwrap())
}
#[test]
fn try_from_test2(){
let color = ConsoleColor::try_from(12).ok();
assert!(color.is_some());
assert_eq!(ConsoleColor::Red, color.unwrap())
}
}