use core::fmt::Write;
use ansi_colours::ansi256_from_rgb;
use syntect::highlighting::{Color, Style};
use tap::Pipe;
fn blend_fg_color(fg: Color, bg: Color) -> Color {
let ratio = match fg.a {
0xff => return fg, x => x as u32, };
let blend = |fg_channel, bg_channel| {
((fg_channel as u32 * ratio + bg_channel as u32 * (255 - ratio)) / 255) as u8
};
let (r, g, b) = (
blend(fg.r, bg.r), blend(fg.g, bg.g), blend(fg.b, bg.b), );
Color { r, g, b, a: 255 } }
pub fn to_ansi_256color(
sty_text_pairs: &[(Style, &str)],
background: bool,
) -> Result<String, core::fmt::Error> {
let mut s = String::new();
let process_bg = |bg: Color| {
let (r, g, b) = (bg.r, bg.g, bg.b);
(r, g, b).pipe(ansi256_from_rgb) };
let process_fg = |sty: &Style| {
blend_fg_color(sty.foreground, sty.background) .pipe(|c| (c.r, c.g, c.b)) .pipe(ansi256_from_rgb) };
sty_text_pairs
.iter()
.try_for_each(|(style, text)| {
if background {
style
.background
.pipe(process_bg)
.pipe(|ansi_bg| write!(s, "\x1b[48;5;{ansi_bg}m"))?
}
process_fg(style).pipe(|ansi_fg| write!(s, "\x1b[38;5;{ansi_fg}m{text}"))
})?;
Ok(s)
}