summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilipp Gesang <phg@phi-gamma.net>2021-11-16 19:12:36 +0100
committerPhilipp Gesang <phg@phi-gamma.net>2021-11-16 19:14:36 +0100
commit689b732184c227b4f49e2b509fad06c1f31c4e4b (patch)
tree9fc5657e20f761333b3df071076175477d76af2e
parente1755da9f1c2755f72cbf843dd653c3f6f71c7e8 (diff)
downloadvtcol-689b732184c227b4f49e2b509fad06c1f31c4e4b.tar.gz
switch RawPalette to integer representation
Introducing a simple type for RGB colors. That awkward string representation for RawPalette got unwieldy quick.
-rw-r--r--src/lib.rs141
-rw-r--r--src/vtcol.rs6
2 files changed, 96 insertions, 51 deletions
diff --git a/src/lib.rs b/src/lib.rs
index 699b462..18e554d 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -127,7 +127,7 @@ const PALETTE_SIZE: usize = 16;
const PALETTE_BYTES: usize = PALETTE_SIZE * 3; /* 16 * sizeof(int) */
const RAW_COLEXPR_SIZE: usize = 6; /* e. g. 0xBADF00 */
-pub type RawPalette<'a> = [&'a str; PALETTE_SIZE];
+pub type RawPalette<'a> = [u32; PALETTE_SIZE];
#[derive(Debug)]
pub enum Color
@@ -216,36 +216,36 @@ pub struct Builtin
/** Vanilla Linux colors. */
const DEFAULT_COLORS: RawPalette = [
- "000000", "aa0000", "00aa00", "aa5500", "0000aa", "aa00aa", "00aaaa",
- "aaaaaa", "555555", "ff5555", "55ff55", "ffff55", "5555ff", "ff55ff",
- "55ffff", "ffffff",
+ 0x000000, 0xaa0000, 0x00aa00, 0xaa5500, 0x0000aa, 0xaa00aa, 0x00aaaa,
+ 0xaaaaaa, 0x555555, 0xff5555, 0x55ff55, 0xffff55, 0x5555ff, 0xff55ff,
+ 0x55ffff, 0xffffff,
];
/** The dark (default) version of the Solarized scheme. */
const SOLARIZED_COLORS_DARK: RawPalette = [
- "002b36", "dc322f", "859900", "b58900", "268bd2", "d33682", "2aa198",
- "eee8d5", "002b36", "cb4b16", "586e75", "657b83", "839496", "6c71c4",
- "93a1a1", "fdf6e3",
+ 0x002b36, 0xdc322f, 0x859900, 0xb58900, 0x268bd2, 0xd33682, 0x2aa198,
+ 0xeee8d5, 0x002b36, 0xcb4b16, 0x586e75, 0x657b83, 0x839496, 0x6c71c4,
+ 0x93a1a1, 0xfdf6e3,
];
/** The light version of the Solarized theme. */
const SOLARIZED_COLORS_LIGHT: RawPalette = [
- "eee8d5", "dc322f", "859900", "b58900", "268bd2", "d33682", "2aa198",
- "073642", "fdf6e3", "cb4b16", "93a1a1", "839496", "657b83", "6c71c4",
- "586e75", "002b36",
+ 0xeee8d5, 0xdc322f, 0x859900, 0xb58900, 0x268bd2, 0xd33682, 0x2aa198,
+ 0x073642, 0xfdf6e3, 0xcb4b16, 0x93a1a1, 0x839496, 0x657b83, 0x6c71c4,
+ 0x586e75, 0x002b36,
];
/** Bright green monochrome terminal. */
const MONOCHROME_PHOSPHOR: RawPalette = [
- "000000", "68fc68", "68fc68", "68fc68", "68fc68", "68fc68", "68fc68",
- "68fc68", "68fc68", "68fc68", "68fc68", "68fc68", "68fc68", "68fc68",
- "68fc68", "68fc68",
+ 0x000000, 0x68fc68, 0x68fc68, 0x68fc68, 0x68fc68, 0x68fc68, 0x68fc68,
+ 0x68fc68, 0x68fc68, 0x68fc68, 0x68fc68, 0x68fc68, 0x68fc68, 0x68fc68,
+ 0x68fc68, 0x68fc68,
];
const DUMMY_COLORS: RawPalette = [
- "000000", "ffffff", "000000", "ffffff", "000000", "ffffff", "000000",
- "ffffff", "000000", "ffffff", "000000", "ffffff", "000000", "ffffff",
- "000000", "ffffff",
+ 0x000000, 0xffffff, 0x000000, 0xffffff, 0x000000, 0xffffff, 0x000000,
+ 0xffffff, 0x000000, 0xffffff, 0x000000, 0xffffff, 0x000000, 0xffffff,
+ 0x000000, 0xffffff,
];
pub const BUILTIN_SCHEMES: &[Builtin] = &[
@@ -386,29 +386,62 @@ impl From<Palette> for Scheme
}
}
-fn nibble_of_char(chr: u8) -> u8
+#[inline]
+fn nibble_of_char(chr: u8) -> io::Result<u8>
{
match chr {
- b'0'..=b'9' => chr - b'0',
- b'a'..=b'f' => chr - b'a' + 10,
- b'A'..=b'F' => chr - b'A' + 10,
- _ => 0,
+ b'0'..=b'9' => Ok(chr - b'0'),
+ b'a'..=b'f' => Ok(chr - b'a' + 10),
+ b'A'..=b'F' => Ok(chr - b'A' + 10),
+ _ =>
+ Err(io::Error::new(
+ io::ErrorKind::Other,
+ format!("junk input ‘{}’ does not represent a hex digit", chr,),
+ )),
}
}
macro_rules! byte_of_hex {
($ar:ident, $off:expr) => {
- (nibble_of_char($ar[$off])) << 4 | nibble_of_char($ar[$off + 1]) as u8
+ (nibble_of_char($ar[$off])? << 4 | nibble_of_char($ar[$off + 1])?) as u8
};
}
-fn rgb_of_hex_triplet(def: &str) -> (u8, u8, u8)
+struct Rgb(u8, u8, u8);
+
+impl Rgb
+{
+ fn r(&self) -> u8 { self.0 }
+
+ fn g(&self) -> u8 { self.1 }
+
+ fn b(&self) -> u8 { self.2 }
+}
+
+impl TryFrom<&[u8; 6]> for Rgb
+{
+ type Error = io::Error;
+
+ fn try_from(hex: &[u8; RAW_COLEXPR_SIZE]) -> io::Result<Self>
+ {
+ let r: u8 = byte_of_hex!(hex, 0);
+ let g: u8 = byte_of_hex!(hex, 2);
+ let b: u8 = byte_of_hex!(hex, 4);
+
+ Ok(Self(r, g, b))
+ }
+}
+
+impl From<u32> for Rgb
{
- let bytes = def.as_bytes();
- let r: u8 = byte_of_hex!(bytes, 0);
- let g: u8 = byte_of_hex!(bytes, 2);
- let b: u8 = byte_of_hex!(bytes, 4);
- (r, g, b)
+ fn from(rgb: u32) -> Self
+ {
+ let b: u8 = (rgb & 0xff) as u8;
+ let g: u8 = ((rgb >> 8) & 0xff) as u8;
+ let r: u8 = ((rgb >> 16) & 0xff) as u8;
+
+ Self(r, g, b)
+ }
}
#[derive(Eq, PartialEq, Clone)]
@@ -421,12 +454,15 @@ impl Palette
pub fn dummy() -> Self { Self::from(&DUMMY_COLORS) }
- pub fn from_buffered_reader(reader: &mut dyn std::io::BufRead) -> Self
+ pub fn from_buffered_reader(
+ reader: &mut dyn std::io::BufRead,
+ ) -> io::Result<Self>
{
let mut pal_idx: usize = 0;
let mut pal: [u8; PALETTE_BYTES] = [0; PALETTE_BYTES];
let mut line: String = String::new();
+ let mut col: [u8; RAW_COLEXPR_SIZE] = [0; RAW_COLEXPR_SIZE];
while reader.read_line(&mut line).is_ok() {
let len = line.len();
if len == 0 {
@@ -446,21 +482,27 @@ impl Palette
let off = off + 1;
if off > len - 6 {
/* no room left for color definition after '#' char */
- panic!("invalid color definition: {}", line);
+ return Err(io::Error::new(
+ io::ErrorKind::Other,
+ format!("invalid color definition: {}", line),
+ ));
}
- let col = &line[off..(off + RAW_COLEXPR_SIZE)];
- let (r, g, b) = rgb_of_hex_triplet(col);
- pal[pal_idx] = r;
- pal[pal_idx + 1] = g;
- pal[pal_idx + 2] = b;
+ col.copy_from_slice(
+ &line.as_bytes()[off..(off + RAW_COLEXPR_SIZE)],
+ );
+
+ let rgb = Rgb::try_from(&col)?;
+ pal[pal_idx] = rgb.r();
+ pal[pal_idx + 1] = rgb.g();
+ pal[pal_idx + 2] = rgb.b();
pal_idx = (pal_idx + 3) % PALETTE_BYTES;
}
}
line.truncate(0);
}
- Self(pal)
+ Ok(Self(pal))
}
#[allow(rustdoc::invalid_rust_codeblocks)]
@@ -500,7 +542,7 @@ impl Palette
Ok(())
}
- pub fn from_file(fname: &Path) -> Self
+ pub fn from_file(fname: &Path) -> io::Result<Self>
{
/* Check if file exists
*/
@@ -519,7 +561,7 @@ impl Palette
/* [Palette::from_file] */
- pub fn from_stdin() -> Self
+ pub fn from_stdin() -> io::Result<Self>
{
let mut reader = std::io::BufReader::new(std::io::stdin());
@@ -570,15 +612,18 @@ impl fmt::Debug for Palette
} /* [impl fmt::Debug for Palette] */
/** Obtain a ``Palette`` from a ``Scheme``. */
-impl From<&Scheme> for Palette
+impl TryFrom<&Scheme> for Palette
{
- fn from(scm: &Scheme) -> Self
+ type Error = io::Error;
+
+ fn try_from(scm: &Scheme) -> io::Result<Self>
{
match scm {
- Scheme::Builtin(Builtin { palette, .. }) => Self::from(*palette),
+ Scheme::Builtin(Builtin { palette, .. }) =>
+ Ok(Self::from(*palette)),
Scheme::Custom(None) => Self::from_stdin(),
Scheme::Custom(Some(ref fname)) => Self::from_file(fname),
- Scheme::Palette(pal) => pal.clone(),
+ Scheme::Palette(pal) => Ok(pal.clone()),
}
}
}
@@ -591,11 +636,11 @@ impl From<&RawPalette<'_>> for Palette
let mut idx: usize = 0;
let mut pal: [u8; PALETTE_BYTES] = [0; PALETTE_BYTES];
- for def in colors.iter() {
- let (r, g, b) = rgb_of_hex_triplet(*def);
- pal[idx] = r;
- pal[idx + 1] = g;
- pal[idx + 2] = b;
+ for &def in colors.iter() {
+ let rgb = Rgb::from(def);
+ pal[idx] = rgb.r();
+ pal[idx + 1] = rgb.g();
+ pal[idx + 2] = rgb.b();
//println!(">> {} -> {:X} {:X} {:X}", def, r, g, b);
idx += 3;
}
@@ -715,7 +760,7 @@ impl Console
#[inline]
pub fn apply_scheme(&self, scm: &Scheme) -> io::Result<()>
{
- self.apply_palette(&Palette::from(scm))
+ self.apply_palette(&Palette::try_from(scm)?)
}
}
diff --git a/src/vtcol.rs b/src/vtcol.rs
index d3399fc..b0c4b85 100644
--- a/src/vtcol.rs
+++ b/src/vtcol.rs
@@ -187,11 +187,11 @@ impl<'a> Job
)
}),
Scheme::Custom(None) =>
- Palette::from_stdin().dump(&mut out).map_err(|e| {
+ Palette::from_stdin()?.dump(&mut out).map_err(|e| {
anyhow!("error loading palette from stdin: {}", e)
}),
Scheme::Custom(Some(fname)) =>
- Palette::from_file(&fname).dump(&mut out).map_err(|e| {
+ Palette::from_file(&fname)?.dump(&mut out).map_err(|e| {
anyhow!(
"error loading palette from file [{}]: {}",
fname.display(),
@@ -251,7 +251,7 @@ impl<'a> Job
let fd = Console::current()?;
vrb!("console fd: {}", fd);
- if fd.current_palette()? == Palette::from(&one) {
+ if fd.current_palette()? == Palette::try_from(&one)? {
Self::set_scheme(two)
} else {
Self::set_scheme(one)