use core::fmt::{self, Display, Formatter}; pub enum Colored { Color(T, Colorer, Colorer), Just(T) } impl Display for Colored { fn fmt(&self, fmt: &mut Formatter) -> fmt::Result { match self { Colored::Color(t, before, after) => { write!(fmt, "{}{}{}", before, t, after) }, 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<&'static str> 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 + ?Sized> { 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 termion::color; 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: color::Fg<&'static dyn color::Color>, stack: color::Fg<&'static dyn color::Color>, nop: color::Fg<&'static dyn color::Color>, stop: color::Fg<&'static dyn color::Color>, control: color::Fg<&'static dyn color::Color>, data: color::Fg<&'static dyn color::Color>, comparison: color::Fg<&'static dyn color::Color>, invalid: color::Fg<&'static dyn color::Color>, platform: color::Fg<&'static dyn color::Color>, misc: color::Fg<&'static dyn color::Color>, register: color::Fg<&'static dyn color::Color>, program_counter: color::Fg<&'static dyn color::Color>, number: color::Fg<&'static dyn color::Color>, zero: color::Fg<&'static dyn color::Color>, one: color::Fg<&'static dyn color::Color>, minus_one: color::Fg<&'static dyn color::Color>, function: color::Fg<&'static dyn color::Color>, symbol: color::Fg<&'static dyn color::Color>, address: color::Fg<&'static dyn color::Color>, } #[cfg(feature="colorize")] impl Default for ColorSettings { fn default() -> ColorSettings { ColorSettings { arithmetic: color::Fg(&color::LightYellow), stack: color::Fg(&color::Magenta), nop: color::Fg(&color::Blue), stop: color::Fg(&color::LightRed), control: color::Fg(&color::Green), data: color::Fg(&color::LightMagenta), comparison: color::Fg(&color::Yellow), invalid: color::Fg(&color::Red), platform: color::Fg(&color::Cyan), misc: color::Fg(&color::LightCyan), register: color::Fg(&color::Cyan), program_counter: color::Fg(&color::Red), number: color::Fg(&color::White), zero: color::Fg(&color::White), one: color::Fg(&color::White), minus_one: color::Fg(&color::White), function: color::Fg(&color::LightGreen), symbol: color::Fg(&color::LightGreen), address: color::Fg(&color::Green), } } } impl YaxColors> for ColorSettings { fn arithmetic_op(&self, t: T) -> Colored> { Colored::Color(t, self.arithmetic, color::Fg(&color::Reset)) } fn stack_op(&self, t: T) -> Colored> { Colored::Color(t, self.stack, color::Fg(&color::Reset)) } fn nop_op(&self, t: T) -> Colored> { Colored::Color(t, self.nop, color::Fg(&color::Reset)) } fn stop_op(&self, t: T) -> Colored> { Colored::Color(t, self.stop, color::Fg(&color::Reset)) } fn control_flow_op(&self, t: T) -> Colored> { Colored::Color(t, self.control, color::Fg(&color::Reset)) } fn data_op(&self, t: T) -> Colored> { Colored::Color(t, self.data, color::Fg(&color::Reset)) } fn comparison_op(&self, t: T) -> Colored> { Colored::Color(t, self.comparison, color::Fg(&color::Reset)) } fn invalid_op(&self, t: T) -> Colored> { Colored::Color(t, self.invalid, color::Fg(&color::Reset)) } fn misc_op(&self, t: T) -> Colored> { Colored::Color(t, self.misc, color::Fg(&color::Reset)) } fn platform_op(&self, t: T) -> Colored> { Colored::Color(t, self.platform, color::Fg(&color::Reset)) } fn register(&self, t: T) -> Colored> { Colored::Color(t, self.register, color::Fg(&color::Reset)) } fn program_counter(&self, t: T) -> Colored> { Colored::Color(t, self.program_counter, color::Fg(&color::Reset)) } fn number(&self, t: T) -> Colored> { Colored::Color(t, self.number, color::Fg(&color::Reset)) } fn zero(&self, t: T) -> Colored> { Colored::Color(t, self.zero, color::Fg(&color::Reset)) } fn one(&self, t: T) -> Colored> { Colored::Color(t, self.one, color::Fg(&color::Reset)) } fn minus_one(&self, t: T) -> Colored> { Colored::Color(t, self.minus_one, color::Fg(&color::Reset)) } fn address(&self, t: T) -> Colored> { Colored::Color(t, self.address, color::Fg(&color::Reset)) } fn symbol(&self, t: T) -> Colored> { Colored::Color(t, self.symbol, color::Fg(&color::Reset)) } fn function(&self, t: T) -> Colored> { Colored::Color(t, self.function, color::Fg(&color::Reset)) } } 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) } } */