use core::fmt::{self, Display, Formatter}; #[cfg(feature="colors")] use crossterm::style; #[cfg(feature="colors")] pub enum Colored { Color(T, style::Color), Just(T) } #[cfg(feature="colors")] impl Display for Colored { fn fmt(&self, fmt: &mut Formatter) -> fmt::Result { match self { Colored::Color(t, before) => { write!(fmt, "{}", style::style(t).with(*before)) }, Colored::Just(t) => { write!(fmt, "{}", t) } } } } #[cfg(not(feature="colors"))] pub enum Colored { Just(T) } #[cfg(not(feature="colors"))] impl Display for Colored { fn fmt(&self, fmt: &mut Formatter) -> fmt::Result { match self { Colored::Just(t) => { write!(fmt, "{}", t) } } } } pub trait YaxColors { fn arithmetic_op(&self, t: T) -> Colored; fn stack_op(&self, t: T) -> Colored; fn nop_op(&self, t: T) -> Colored; fn stop_op(&self, t: T) -> Colored; fn control_flow_op(&self, t: T) -> Colored; fn data_op(&self, t: T) -> Colored; fn comparison_op(&self, t: T) -> Colored; fn invalid_op(&self, t: T) -> Colored; fn platform_op(&self, t: T) -> Colored; fn misc_op(&self, t: T) -> Colored; fn register(&self, t: T) -> Colored; fn program_counter(&self, t: T) -> Colored; fn number(&self, t: T) -> Colored; fn zero(&self, t: T) -> Colored; fn one(&self, t: T) -> Colored; fn minus_one(&self, t: T) -> Colored; fn address(&self, t: T) -> Colored; fn symbol(&self, t: T) -> Colored; fn function(&self, t: T) -> Colored; } pub struct NoColors; impl YaxColors for NoColors { fn arithmetic_op(&self, t: T) -> Colored { Colored::Just(t) } fn stack_op(&self, t: T) -> Colored { Colored::Just(t) } fn nop_op(&self, t: T) -> Colored { Colored::Just(t) } fn stop_op(&self, t: T) -> Colored { Colored::Just(t) } fn control_flow_op(&self, t: T) -> Colored { Colored::Just(t) } fn data_op(&self, t: T) -> Colored { Colored::Just(t) } fn comparison_op(&self, t: T) -> Colored { Colored::Just(t) } fn invalid_op(&self, t: T) -> Colored { Colored::Just(t) } fn platform_op(&self, t: T) -> Colored { Colored::Just(t) } fn misc_op(&self, t: T) -> Colored { Colored::Just(t) } fn register(&self, t: T) -> Colored { Colored::Just(t) } fn program_counter(&self, t: T) -> Colored { Colored::Just(t) } fn number(&self, t: T) -> Colored { Colored::Just(t) } fn zero(&self, t: T) -> Colored { Colored::Just(t) } fn one(&self, t: T) -> Colored { Colored::Just(t) } fn minus_one(&self, t: T) -> Colored { Colored::Just(t) } fn address(&self, t: T) -> Colored { Colored::Just(t) } fn symbol(&self, t: T) -> Colored { Colored::Just(t) } fn function(&self, t: T) -> Colored { Colored::Just(t) } } pub trait Colorize { fn colorize(&self, colors: &Y, out: &mut T) -> fmt::Result; } #[cfg(feature="colors")] pub use termion_color::ColorSettings; #[cfg(feature="colors")] mod termion_color { use core::fmt::Display; use crossterm::style; use serde::Serialize; use crate::color::{Colored, YaxColors}; #[cfg(feature="use-serde")] impl Serialize for ColorSettings { fn serialize(&self, serializer: S) -> Result { use serde::ser::SerializeStruct; let s = serializer.serialize_struct("ColorSettings", 0)?; s.end() } } pub struct ColorSettings { arithmetic: style::Color, stack: style::Color, nop: style::Color, stop: style::Color, control: style::Color, data: style::Color, comparison: style::Color, invalid: style::Color, platform: style::Color, misc: style::Color, register: style::Color, program_counter: style::Color, number: style::Color, zero: style::Color, one: style::Color, minus_one: style::Color, function: style::Color, symbol: style::Color, address: style::Color, } impl Default for ColorSettings { fn default() -> ColorSettings { ColorSettings { arithmetic: style::Color::Yellow, stack: style::Color::DarkMagenta, nop: style::Color::DarkBlue, stop: style::Color::Red, control: style::Color::DarkGreen, data: style::Color::Magenta, comparison: style::Color::DarkYellow, invalid: style::Color::DarkRed, platform: style::Color::DarkCyan, misc: style::Color::Cyan, register: style::Color::DarkCyan, program_counter: style::Color::DarkRed, number: style::Color::White, zero: style::Color::White, one: style::Color::White, minus_one: style::Color::White, function: style::Color::Green, symbol: style::Color::Green, address: style::Color::DarkGreen, } } } impl YaxColors for ColorSettings { fn arithmetic_op(&self, t: T) -> Colored { Colored::Color(t, self.arithmetic) } fn stack_op(&self, t: T) -> Colored { Colored::Color(t, self.stack) } fn nop_op(&self, t: T) -> Colored { Colored::Color(t, self.nop) } fn stop_op(&self, t: T) -> Colored { Colored::Color(t, self.stop) } fn control_flow_op(&self, t: T) -> Colored { Colored::Color(t, self.control) } fn data_op(&self, t: T) -> Colored { Colored::Color(t, self.data) } fn comparison_op(&self, t: T) -> Colored { Colored::Color(t, self.comparison) } fn invalid_op(&self, t: T) -> Colored { Colored::Color(t, self.invalid) } fn misc_op(&self, t: T) -> Colored { Colored::Color(t, self.misc) } fn platform_op(&self, t: T) -> Colored { Colored::Color(t, self.platform) } fn register(&self, t: T) -> Colored { Colored::Color(t, self.register) } fn program_counter(&self, t: T) -> Colored { Colored::Color(t, self.program_counter) } fn number(&self, t: T) -> Colored { Colored::Color(t, self.number) } fn zero(&self, t: T) -> Colored { Colored::Color(t, self.zero) } fn one(&self, t: T) -> Colored { Colored::Color(t, self.one) } fn minus_one(&self, t: T) -> Colored { Colored::Color(t, self.minus_one) } fn address(&self, t: T) -> Colored { Colored::Color(t, self.address) } fn symbol(&self, t: T) -> Colored { Colored::Color(t, self.symbol) } fn function(&self, t: T) -> Colored { Colored::Color(t, self.function) } } impl <'a> YaxColors for Option<&'a ColorSettings> { fn arithmetic_op(&self, t: T) -> Colored { match self { Some(colors) => { colors.arithmetic_op(t) } None => { Colored::Just(t) } } } fn stack_op(&self, t: T) -> Colored { match self { Some(colors) => { colors.stack_op(t) } None => { Colored::Just(t) } } } fn nop_op(&self, t: T) -> Colored { match self { Some(colors) => { colors.nop_op(t) } None => { Colored::Just(t) } } } fn stop_op(&self, t: T) -> Colored { match self { Some(colors) => { colors.stop_op(t) } None => { Colored::Just(t) } } } fn control_flow_op(&self, t: T) -> Colored { match self { Some(colors) => { colors.control_flow_op(t) } None => { Colored::Just(t) } } } fn data_op(&self, t: T) -> Colored { match self { Some(colors) => { colors.data_op(t) } None => { Colored::Just(t) } } } fn comparison_op(&self, t: T) -> Colored { match self { Some(colors) => { colors.comparison_op(t) } None => { Colored::Just(t) } } } fn invalid_op(&self, t: T) -> Colored { match self { Some(colors) => { colors.invalid_op(t) } None => { Colored::Just(t) } } } fn misc_op(&self, t: T) -> Colored { match self { Some(colors) => { colors.misc_op(t) } None => { Colored::Just(t) } } } fn platform_op(&self, t: T) -> Colored { match self { Some(colors) => { colors.platform_op(t) } None => { Colored::Just(t) } } } fn register(&self, t: T) -> Colored { match self { Some(colors) => { colors.register(t) } None => { Colored::Just(t) } } } fn program_counter(&self, t: T) -> Colored { match self { Some(colors) => { colors.program_counter(t) } None => { Colored::Just(t) } } } fn number(&self, t: T) -> Colored { match self { Some(colors) => { colors.number(t) } None => { Colored::Just(t) } } } fn zero(&self, t: T) -> Colored { match self { Some(colors) => { colors.zero(t) } None => { Colored::Just(t) } } } fn one(&self, t: T) -> Colored { match self { Some(colors) => { colors.one(t) } None => { Colored::Just(t) } } } fn minus_one(&self, t: T) -> Colored { match self { Some(colors) => { colors.minus_one(t) } None => { Colored::Just(t) } } } fn address(&self, t: T) -> Colored { match self { Some(colors) => { colors.address(t) } None => { Colored::Just(t) } } } fn symbol(&self, t: T) -> Colored { match self { Some(colors) => { colors.symbol(t) } None => { Colored::Just(t) } } } fn function(&self, t: T) -> Colored { match self { Some(colors) => { colors.function(t) } None => { Colored::Just(t) } } } } } /* * can this be a derivable trait or something? */ /* impl Display for T { fn fmt(&self, fmt: &mut Formatter) -> fmt::Result { self.colorize(None, fmt) } } */ /* * and make this auto-derive from a ShowContextual impl? */ /* impl Colorize for T where T: ShowContextual { fn colorize(&self, colors: Option<&ColorSettings>, fmt: &mut Formatter) -> fmt::Result { self.contextualize(colors, None, fmt) } } */