use std::cell::RefCell;
use super::theme::{Theme, ThemeName};
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct AnsiRemap(pub [u8; 9]);
pub fn remap_from_palette(p: [u8; 6]) -> AnsiRemap {
let [c1, c2, c3, c4, c5, c6] = p;
AnsiRemap([
c6, c5, c2, c4, c3, c3, c2, c1, c6, ])
}
thread_local! {
static ACTIVE: RefCell<Option<AnsiRemap>> = const { RefCell::new(None) };
}
pub fn set(remap: Option<AnsiRemap>) {
ACTIVE.with(|a| *a.borrow_mut() = remap);
}
pub fn clear() {
set(None);
}
pub fn apply_palette(palette: [u8; 6]) {
set(Some(remap_from_palette(palette)));
}
pub fn apply_theme(name: ThemeName) {
apply_palette(Theme::palette_values(name));
}
pub fn is_active() -> bool {
ACTIVE.with(|a| a.borrow().is_some())
}
pub fn remap(n: i16) -> Option<u8> {
if !(0..=8).contains(&n) {
return None;
}
ACTIVE.with(|a| a.borrow().map(|r| r.0[n as usize]))
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn no_remap_by_default() {
assert!(!is_active());
assert_eq!(remap(2), None);
}
#[test]
fn apply_theme_activates_and_remaps() {
apply_theme(ThemeName::BladeRunner);
assert!(is_active());
let pal = Theme::palette_values(ThemeName::BladeRunner);
assert_eq!(remap(6), Some(pal[1]));
assert_eq!(remap(7), Some(pal[0]));
}
#[test]
fn clear_deactivates() {
apply_theme(ThemeName::NeonSprawl);
assert!(is_active());
clear();
assert!(!is_active());
assert_eq!(remap(3), None);
}
#[test]
fn out_of_range_never_remapped() {
apply_theme(ThemeName::NeonSprawl);
assert_eq!(remap(-1), None); assert_eq!(remap(9), None);
assert_eq!(remap(255), None);
}
#[test]
fn remap_from_palette_layout() {
let r = remap_from_palette([10, 20, 30, 40, 50, 60]);
assert_eq!(r.0[0], 60); assert_eq!(r.0[2], 20); assert_eq!(r.0[6], 20); assert_eq!(r.0[7], 10); assert_eq!(r.0[8], 60); }
#[test]
fn apply_palette_matches_remap_from_palette() {
apply_palette([1, 2, 3, 4, 5, 6]);
assert_eq!(remap(0), Some(6));
assert_eq!(remap(7), Some(1));
clear();
}
}