diff --git a/kkdisp/src/component.rs b/kkdisp/src/component.rs index ccefd8b..4c0cc55 100644 --- a/kkdisp/src/component.rs +++ b/kkdisp/src/component.rs @@ -1,6 +1,6 @@ use crate::theme::{Color, ColorSet}; -#[derive(PartialEq, Debug, Clone)] +#[derive(Eq, Debug, Clone)] pub enum Component { X(usize), String(String), @@ -9,7 +9,34 @@ pub enum Component { Bg(Color), } -#[derive(PartialEq, Debug, Clone, Copy)] +impl PartialEq for Component { + fn eq(&self, other: &Self) -> bool { + match self { + Self::X(x) => match other { + Self::X(other_x) => x == other_x, + _ => false, + }, + Self::String(s) => match other { + Self::String(other_s) => s == other_s, + _ => false, + }, + Self::Clear(clr) => match other { + Self::Clear(other_clr) => clr == other_clr, + _ => false, + }, + Self::Fg(c) => match other { + Self::Fg(other_c) => c == other_c, + _ => false, + }, + Self::Bg(c) => match other { + Self::Bg(other_c) => c == other_c, + _ => false, + }, + } + } +} + +#[derive(PartialEq, Debug, Clone, Copy, Eq)] pub enum Clear { Line, Screen, diff --git a/kkdisp/src/theme.rs b/kkdisp/src/theme.rs index c514f84..1009407 100644 --- a/kkdisp/src/theme.rs +++ b/kkdisp/src/theme.rs @@ -1,5 +1,4 @@ use serde::{de::Visitor, Deserialize, Serialize}; -use std::ops::Deref; use termion::color; @@ -14,14 +13,6 @@ pub struct ColorSet { pub bg: Color, } -impl PartialEq for Color { - fn eq(&self, other: &Self) -> bool { - self.0 .0 == other.0 .0 - && self.0 .1 == other.0 .1 - && self.0 .2 == other.0 .2 - } -} - impl Default for ColorSet { fn default() -> Self { Self { @@ -34,18 +25,18 @@ impl Default for ColorSet { impl ToString for ColorSet { #[inline(always)] fn to_string(&self) -> String { - self.bg.bg_string() + &self.fg.fg_string() + self.bg.bg() + &self.fg.fg() } } -#[derive(Clone, Copy, Debug)] -pub struct Color(color::Rgb); +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub struct Color(u8, u8, u8); impl Color { - pub const BLACK: Color = Color(color::Rgb(0, 0, 0)); - pub const RED: Color = Color(color::Rgb(255, 0, 0)); - pub const GREEN: Color = Color(color::Rgb(0, 255, 0)); - pub const BLUE: Color = Color(color::Rgb(0, 0, 255)); + pub const BLACK: Color = Color(0, 0, 0); + pub const RED: Color = Color(255, 0, 0); + pub const GREEN: Color = Color(0, 255, 0); + pub const BLUE: Color = Color(0, 0, 255); } impl Serialize for Color { @@ -53,10 +44,9 @@ impl Serialize for Color { where S: serde::Serializer, { - let rgb = self.0; serializer.serialize_str(&format!( "#{:02X}{:02X}{:02X}", - rgb.0, rgb.1, rgb.2, + self.0, self.1, self.2, )) } } @@ -103,13 +93,15 @@ impl<'de> Deserialize<'de> for Color { } } -impl Deref for Color { - type Target = color::Rgb; - - fn deref(&self) -> &Self::Target { - &self.0 +impl Color { + pub fn bg(&self) -> String { + color::Rgb(self.0, self.1, self.2).bg_string() + } + pub fn fg(&self) -> String { + color::Rgb(self.0, self.1, self.2).fg_string() } } + impl TryFrom for Color { type Error = anyhow::Error; @@ -129,14 +121,14 @@ impl TryFrom<&str> for Color { if value.starts_with('#') { i = 1; } - Ok(Self(color::Rgb( + Ok(Self( u8::from_str_radix(&value[i..i + 2], 16) .map_err(|_| anyhow::anyhow!("red hex"))?, u8::from_str_radix(&value[i + 2..i + 4], 16) .map_err(|_| anyhow::anyhow!("green hex"))?, u8::from_str_radix(&value[i + 4..i + 6], 16) .map_err(|_| anyhow::anyhow!("blue hex"))?, - ))) + )) } } diff --git a/kkdisp/src/token.rs b/kkdisp/src/token.rs index 274553e..6412dbb 100644 --- a/kkdisp/src/token.rs +++ b/kkdisp/src/token.rs @@ -1,6 +1,5 @@ use crate::{component::Component, theme::Color}; -// (line (centered (limited (padded "hello world")))) #[derive(Debug, Clone)] pub enum Token { Centered(Box), @@ -226,7 +225,7 @@ mod tests { .fg(Color::GREEN) .centered(), vec![ - Component::X(0), + Component::X((WIDTH - 11) / 2), Component::Fg(Color::GREEN), Component::String("start".into()), Component::Fg(Color::BLUE), @@ -241,20 +240,26 @@ mod tests { let (name, token, expected) = test; eprintln!("token: {:#?}", &token); let actual = token.with_width(WIDTH); - let actual_fmt = format!("{:#?}", &actual); assert!( - expected - .clone() - .iter() - .zip(actual.iter()) - .filter(|&(l, r)| l == r) - .count() - != 0, - "{} expected: {:#?} actual: {}", - name, - expected, - actual_fmt, - ) + expected.len() == actual.len(), + "<{}>: length mismatch. expected {} actual {}", + &name, + expected.len(), + actual.len(), + ); + for (i, exp) in expected.into_iter().enumerate() { + let act = &actual[i]; + assert!( + exp == *act, + "<{}>: component at index {} mismatch. + expected:\n{:#?} + actual:\n{:#?}", + &name, + i, + exp, + act, + ); + } }) } }