fixed tests + refactored color + added string concatenation

This commit is contained in:
emilis 2023-01-17 12:40:36 +00:00
parent 80425f9aff
commit dd1fe448a7
3 changed files with 66 additions and 42 deletions

View File

@ -1,6 +1,6 @@
use crate::theme::{Color, ColorSet}; use crate::theme::{Color, ColorSet};
#[derive(PartialEq, Debug, Clone)] #[derive(Eq, Debug, Clone)]
pub enum Component { pub enum Component {
X(usize), X(usize),
String(String), String(String),
@ -9,7 +9,34 @@ pub enum Component {
Bg(Color), 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 { pub enum Clear {
Line, Line,
Screen, Screen,

View File

@ -1,5 +1,4 @@
use serde::{de::Visitor, Deserialize, Serialize}; use serde::{de::Visitor, Deserialize, Serialize};
use std::ops::Deref;
use termion::color; use termion::color;
@ -14,14 +13,6 @@ pub struct ColorSet {
pub bg: Color, 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 { impl Default for ColorSet {
fn default() -> Self { fn default() -> Self {
Self { Self {
@ -34,18 +25,18 @@ impl Default for ColorSet {
impl ToString for ColorSet { impl ToString for ColorSet {
#[inline(always)] #[inline(always)]
fn to_string(&self) -> String { fn to_string(&self) -> String {
self.bg.bg_string() + &self.fg.fg_string() self.bg.bg() + &self.fg.fg()
} }
} }
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct Color(color::Rgb); pub struct Color(u8, u8, u8);
impl Color { impl Color {
pub const BLACK: Color = Color(color::Rgb(0, 0, 0)); pub const BLACK: Color = Color(0, 0, 0);
pub const RED: Color = Color(color::Rgb(255, 0, 0)); pub const RED: Color = Color(255, 0, 0);
pub const GREEN: Color = Color(color::Rgb(0, 255, 0)); pub const GREEN: Color = Color(0, 255, 0);
pub const BLUE: Color = Color(color::Rgb(0, 0, 255)); pub const BLUE: Color = Color(0, 0, 255);
} }
impl Serialize for Color { impl Serialize for Color {
@ -53,10 +44,9 @@ impl Serialize for Color {
where where
S: serde::Serializer, S: serde::Serializer,
{ {
let rgb = self.0;
serializer.serialize_str(&format!( serializer.serialize_str(&format!(
"#{:02X}{:02X}{:02X}", "#{: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 { impl Color {
type Target = color::Rgb; pub fn bg(&self) -> String {
color::Rgb(self.0, self.1, self.2).bg_string()
fn deref(&self) -> &Self::Target { }
&self.0 pub fn fg(&self) -> String {
color::Rgb(self.0, self.1, self.2).fg_string()
} }
} }
impl TryFrom<String> for Color { impl TryFrom<String> for Color {
type Error = anyhow::Error; type Error = anyhow::Error;
@ -129,14 +121,14 @@ impl TryFrom<&str> for Color {
if value.starts_with('#') { if value.starts_with('#') {
i = 1; i = 1;
} }
Ok(Self(color::Rgb( Ok(Self(
u8::from_str_radix(&value[i..i + 2], 16) u8::from_str_radix(&value[i..i + 2], 16)
.map_err(|_| anyhow::anyhow!("red hex"))?, .map_err(|_| anyhow::anyhow!("red hex"))?,
u8::from_str_radix(&value[i + 2..i + 4], 16) u8::from_str_radix(&value[i + 2..i + 4], 16)
.map_err(|_| anyhow::anyhow!("green hex"))?, .map_err(|_| anyhow::anyhow!("green hex"))?,
u8::from_str_radix(&value[i + 4..i + 6], 16) u8::from_str_radix(&value[i + 4..i + 6], 16)
.map_err(|_| anyhow::anyhow!("blue hex"))?, .map_err(|_| anyhow::anyhow!("blue hex"))?,
))) ))
} }
} }

View File

@ -1,6 +1,5 @@
use crate::{component::Component, theme::Color}; use crate::{component::Component, theme::Color};
// (line (centered (limited (padded "hello world"))))
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub enum Token { pub enum Token {
Centered(Box<Token>), Centered(Box<Token>),
@ -226,7 +225,7 @@ mod tests {
.fg(Color::GREEN) .fg(Color::GREEN)
.centered(), .centered(),
vec![ vec![
Component::X(0), Component::X((WIDTH - 11) / 2),
Component::Fg(Color::GREEN), Component::Fg(Color::GREEN),
Component::String("start".into()), Component::String("start".into()),
Component::Fg(Color::BLUE), Component::Fg(Color::BLUE),
@ -241,20 +240,26 @@ mod tests {
let (name, token, expected) = test; let (name, token, expected) = test;
eprintln!("token: {:#?}", &token); eprintln!("token: {:#?}", &token);
let actual = token.with_width(WIDTH); let actual = token.with_width(WIDTH);
let actual_fmt = format!("{:#?}", &actual);
assert!( assert!(
expected expected.len() == actual.len(),
.clone() "<{}>: length mismatch. expected {} actual {}",
.iter() &name,
.zip(actual.iter()) expected.len(),
.filter(|&(l, r)| l == r) actual.len(),
.count() );
!= 0, for (i, exp) in expected.into_iter().enumerate() {
"{} expected: {:#?} actual: {}", let act = &actual[i];
name, assert!(
expected, exp == *act,
actual_fmt, "<{}>: component at index {} mismatch.
) expected:\n{:#?}
actual:\n{:#?}",
&name,
i,
exp,
act,
);
}
}) })
} }
} }