aboutsummaryrefslogtreecommitdiff
path: root/src/color.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/color.rs')
-rw-r--r--src/color.rs386
1 files changed, 386 insertions, 0 deletions
diff --git a/src/color.rs b/src/color.rs
new file mode 100644
index 0000000..4bcbd15
--- /dev/null
+++ b/src/color.rs
@@ -0,0 +1,386 @@
+use core::fmt::{self, Display, Formatter};
+
+pub enum Colored<T: Display, Colorer: Display> {
+ Color(T, Colorer, Colorer),
+ Just(T)
+}
+
+impl <T: Display, Colorer: Display> Display for Colored<T, Colorer> {
+ 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<Color: Display> {
+ fn arithmetic_op<T: Display>(&self, t: T) -> Colored<T, Color>;
+ fn stack_op<T: Display>(&self, t: T) -> Colored<T, Color>;
+ fn nop_op<T: Display>(&self, t: T) -> Colored<T, Color>;
+ fn stop_op<T: Display>(&self, t: T) -> Colored<T, Color>;
+ fn control_flow_op<T: Display>(&self, t: T) -> Colored<T, Color>;
+ fn data_op<T: Display>(&self, t: T) -> Colored<T, Color>;
+ fn comparison_op<T: Display>(&self, t: T) -> Colored<T, Color>;
+ fn invalid_op<T: Display>(&self, t: T) -> Colored<T, Color>;
+ fn platform_op<T: Display>(&self, t: T) -> Colored<T, Color>;
+ fn misc_op<T: Display>(&self, t: T) -> Colored<T, Color>;
+
+ fn register<T: Display>(&self, t: T) -> Colored<T, Color>;
+ fn program_counter<T: Display>(&self, t: T) -> Colored<T, Color>;
+ fn number<T: Display>(&self, t: T) -> Colored<T, Color>;
+ fn zero<T: Display>(&self, t: T) -> Colored<T, Color>;
+ fn one<T: Display>(&self, t: T) -> Colored<T, Color>;
+ fn minus_one<T: Display>(&self, t: T) -> Colored<T, Color>;
+ fn address<T: Display>(&self, t: T) -> Colored<T, Color>;
+ fn symbol<T: Display>(&self, t: T) -> Colored<T, Color>;
+ fn function<T: Display>(&self, t: T) -> Colored<T, Color>;
+}
+
+pub struct NoColors;
+
+impl YaxColors<&'static str> for NoColors {
+ fn arithmetic_op<T: Display>(&self, t: T) -> Colored<T, &'static str> {
+ Colored::Just(t)
+ }
+ fn stack_op<T: Display>(&self, t: T) -> Colored<T, &'static str> {
+ Colored::Just(t)
+ }
+ fn nop_op<T: Display>(&self, t: T) -> Colored<T, &'static str> {
+ Colored::Just(t)
+ }
+ fn stop_op<T: Display>(&self, t: T) -> Colored<T, &'static str> {
+ Colored::Just(t)
+ }
+ fn control_flow_op<T: Display>(&self, t: T) -> Colored<T, &'static str> {
+ Colored::Just(t)
+ }
+ fn data_op<T: Display>(&self, t: T) -> Colored<T, &'static str> {
+ Colored::Just(t)
+ }
+ fn comparison_op<T: Display>(&self, t: T) -> Colored<T, &'static str> {
+ Colored::Just(t)
+ }
+ fn invalid_op<T: Display>(&self, t: T) -> Colored<T, &'static str> {
+ Colored::Just(t)
+ }
+ fn platform_op<T: Display>(&self, t: T) -> Colored<T, &'static str> {
+ Colored::Just(t)
+ }
+ fn misc_op<T: Display>(&self, t: T) -> Colored<T, &'static str> {
+ Colored::Just(t)
+ }
+ fn register<T: Display>(&self, t: T) -> Colored<T, &'static str> {
+ Colored::Just(t)
+ }
+ fn program_counter<T: Display>(&self, t: T) -> Colored<T, &'static str> {
+ Colored::Just(t)
+ }
+ fn number<T: Display>(&self, t: T) -> Colored<T, &'static str> {
+ Colored::Just(t)
+ }
+ fn zero<T: Display>(&self, t: T) -> Colored<T, &'static str> {
+ Colored::Just(t)
+ }
+ fn one<T: Display>(&self, t: T) -> Colored<T, &'static str> {
+ Colored::Just(t)
+ }
+ fn minus_one<T: Display>(&self, t: T) -> Colored<T, &'static str> {
+ Colored::Just(t)
+ }
+ fn address<T: Display>(&self, t: T) -> Colored<T, &'static str> {
+ Colored::Just(t)
+ }
+ fn symbol<T: Display>(&self, t: T) -> Colored<T, &'static str> {
+ Colored::Just(t)
+ }
+ fn function<T: Display>(&self, t: T) -> Colored<T, &'static str> {
+ Colored::Just(t)
+ }
+}
+
+pub trait Colorize<T: fmt::Write, Color: Display, Y: YaxColors<Color> + ?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<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
+ 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<color::Fg<&'static dyn color::Color>> for ColorSettings {
+ fn arithmetic_op<T: Display>(&self, t: T) -> Colored<T, color::Fg<&'static dyn color::Color>> {
+ Colored::Color(t, self.arithmetic, color::Fg(&color::Reset))
+ }
+ fn stack_op<T: Display>(&self, t: T) -> Colored<T, color::Fg<&'static dyn color::Color>> {
+ Colored::Color(t, self.stack, color::Fg(&color::Reset))
+ }
+ fn nop_op<T: Display>(&self, t: T) -> Colored<T, color::Fg<&'static dyn color::Color>> {
+ Colored::Color(t, self.nop, color::Fg(&color::Reset))
+ }
+ fn stop_op<T: Display>(&self, t: T) -> Colored<T, color::Fg<&'static dyn color::Color>> {
+ Colored::Color(t, self.stop, color::Fg(&color::Reset))
+ }
+ fn control_flow_op<T: Display>(&self, t: T) -> Colored<T, color::Fg<&'static dyn color::Color>> {
+ Colored::Color(t, self.control, color::Fg(&color::Reset))
+ }
+ fn data_op<T: Display>(&self, t: T) -> Colored<T, color::Fg<&'static dyn color::Color>> {
+ Colored::Color(t, self.data, color::Fg(&color::Reset))
+ }
+ fn comparison_op<T: Display>(&self, t: T) -> Colored<T, color::Fg<&'static dyn color::Color>> {
+ Colored::Color(t, self.comparison, color::Fg(&color::Reset))
+ }
+ fn invalid_op<T: Display>(&self, t: T) -> Colored<T, color::Fg<&'static dyn color::Color>> {
+ Colored::Color(t, self.invalid, color::Fg(&color::Reset))
+ }
+ fn misc_op<T: Display>(&self, t: T) -> Colored<T, color::Fg<&'static dyn color::Color>> {
+ Colored::Color(t, self.misc, color::Fg(&color::Reset))
+ }
+ fn platform_op<T: Display>(&self, t: T) -> Colored<T, color::Fg<&'static dyn color::Color>> {
+ Colored::Color(t, self.platform, color::Fg(&color::Reset))
+ }
+
+ fn register<T: Display>(&self, t: T) -> Colored<T, color::Fg<&'static dyn color::Color>> {
+ Colored::Color(t, self.register, color::Fg(&color::Reset))
+ }
+ fn program_counter<T: Display>(&self, t: T) -> Colored<T, color::Fg<&'static dyn color::Color>> {
+ Colored::Color(t, self.program_counter, color::Fg(&color::Reset))
+ }
+ fn number<T: Display>(&self, t: T) -> Colored<T, color::Fg<&'static dyn color::Color>> {
+ Colored::Color(t, self.number, color::Fg(&color::Reset))
+ }
+ fn zero<T: Display>(&self, t: T) -> Colored<T, color::Fg<&'static dyn color::Color>> {
+ Colored::Color(t, self.zero, color::Fg(&color::Reset))
+ }
+ fn one<T: Display>(&self, t: T) -> Colored<T, color::Fg<&'static dyn color::Color>> {
+ Colored::Color(t, self.one, color::Fg(&color::Reset))
+ }
+ fn minus_one<T: Display>(&self, t: T) -> Colored<T, color::Fg<&'static dyn color::Color>> {
+ Colored::Color(t, self.minus_one, color::Fg(&color::Reset))
+ }
+ fn address<T: Display>(&self, t: T) -> Colored<T, color::Fg<&'static dyn color::Color>> {
+ Colored::Color(t, self.address, color::Fg(&color::Reset))
+ }
+ fn symbol<T: Display>(&self, t: T) -> Colored<T, color::Fg<&'static dyn color::Color>> {
+ Colored::Color(t, self.symbol, color::Fg(&color::Reset))
+ }
+ fn function<T: Display>(&self, t: T) -> Colored<T, color::Fg<&'static dyn color::Color>> {
+ Colored::Color(t, self.function, color::Fg(&color::Reset))
+ }
+ }
+
+ impl <'a> YaxColors<color::Fg<&'static dyn color::Color>>for Option<&'a ColorSettings> {
+ fn arithmetic_op<T: Display>(&self, t: T) -> Colored<T, color::Fg<&'static dyn color::Color>> {
+ match self {
+ Some(colors) => { colors.arithmetic_op(t) }
+ None => { Colored::Just(t) }
+ }
+ }
+ fn stack_op<T: Display>(&self, t: T) -> Colored<T, color::Fg<&'static dyn color::Color>> {
+ match self {
+ Some(colors) => { colors.stack_op(t) }
+ None => { Colored::Just(t) }
+ }
+ }
+ fn nop_op<T: Display>(&self, t: T) -> Colored<T, color::Fg<&'static dyn color::Color>> {
+ match self {
+ Some(colors) => { colors.nop_op(t) }
+ None => { Colored::Just(t) }
+ }
+ }
+ fn stop_op<T: Display>(&self, t: T) -> Colored<T, color::Fg<&'static dyn color::Color>> {
+ match self {
+ Some(colors) => { colors.stop_op(t) }
+ None => { Colored::Just(t) }
+ }
+ }
+ fn control_flow_op<T: Display>(&self, t: T) -> Colored<T, color::Fg<&'static dyn color::Color>> {
+ match self {
+ Some(colors) => { colors.control_flow_op(t) }
+ None => { Colored::Just(t) }
+ }
+ }
+ fn data_op<T: Display>(&self, t: T) -> Colored<T, color::Fg<&'static dyn color::Color>> {
+ match self {
+ Some(colors) => { colors.data_op(t) }
+ None => { Colored::Just(t) }
+ }
+ }
+ fn comparison_op<T: Display>(&self, t: T) -> Colored<T, color::Fg<&'static dyn color::Color>> {
+ match self {
+ Some(colors) => { colors.comparison_op(t) }
+ None => { Colored::Just(t) }
+ }
+ }
+ fn invalid_op<T: Display>(&self, t: T) -> Colored<T, color::Fg<&'static dyn color::Color>> {
+ match self {
+ Some(colors) => { colors.invalid_op(t) }
+ None => { Colored::Just(t) }
+ }
+ }
+ fn misc_op<T: Display>(&self, t: T) -> Colored<T, color::Fg<&'static dyn color::Color>> {
+ match self {
+ Some(colors) => { colors.misc_op(t) }
+ None => { Colored::Just(t) }
+ }
+ }
+ fn platform_op<T: Display>(&self, t: T) -> Colored<T, color::Fg<&'static dyn color::Color>> {
+ match self {
+ Some(colors) => { colors.platform_op(t) }
+ None => { Colored::Just(t) }
+ }
+ }
+
+ fn register<T: Display>(&self, t: T) -> Colored<T, color::Fg<&'static dyn color::Color>> {
+ match self {
+ Some(colors) => { colors.register(t) }
+ None => { Colored::Just(t) }
+ }
+ }
+ fn program_counter<T: Display>(&self, t: T) -> Colored<T, color::Fg<&'static dyn color::Color>> {
+ match self {
+ Some(colors) => { colors.program_counter(t) }
+ None => { Colored::Just(t) }
+ }
+ }
+ fn number<T: Display>(&self, t: T) -> Colored<T, color::Fg<&'static dyn color::Color>> {
+ match self {
+ Some(colors) => { colors.number(t) }
+ None => { Colored::Just(t) }
+ }
+ }
+ fn zero<T: Display>(&self, t: T) -> Colored<T, color::Fg<&'static dyn color::Color>> {
+ match self {
+ Some(colors) => { colors.zero(t) }
+ None => { Colored::Just(t) }
+ }
+ }
+ fn one<T: Display>(&self, t: T) -> Colored<T, color::Fg<&'static dyn color::Color>> {
+ match self {
+ Some(colors) => { colors.one(t) }
+ None => { Colored::Just(t) }
+ }
+ }
+ fn minus_one<T: Display>(&self, t: T) -> Colored<T, color::Fg<&'static dyn color::Color>> {
+ match self {
+ Some(colors) => { colors.minus_one(t) }
+ None => { Colored::Just(t) }
+ }
+ }
+ fn address<T: Display>(&self, t: T) -> Colored<T, color::Fg<&'static dyn color::Color>> {
+ match self {
+ Some(colors) => { colors.address(t) }
+ None => { Colored::Just(t) }
+ }
+ }
+ fn symbol<T: Display>(&self, t: T) -> Colored<T, color::Fg<&'static dyn color::Color>> {
+ match self {
+ Some(colors) => { colors.symbol(t) }
+ None => { Colored::Just(t) }
+ }
+ }
+ fn function<T: Display>(&self, t: T) -> Colored<T, color::Fg<&'static dyn color::Color>> {
+ match self {
+ Some(colors) => { colors.function(t) }
+ None => { Colored::Just(t) }
+ }
+ }
+ }
+}
+
+/*
+ * can this be a derivable trait or something?
+ */
+/*
+impl <T: Colorize> 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 <T, U> Colorize for T where T: ShowContextual<Ctx=U> {
+ fn colorize(&self, colors: Option<&ColorSettings>, fmt: &mut Formatter) -> fmt::Result {
+ self.contextualize(colors, None, fmt)
+ }
+}
+*/