140 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
			
		
		
	
	
			140 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
use anstyle_wincon::WinconStream as _;
 | 
						|
 | 
						|
fn main() -> Result<(), lexopt::Error> {
 | 
						|
    let args = Args::parse()?;
 | 
						|
    let stdout = std::io::stdout();
 | 
						|
    let mut stdout = stdout.lock();
 | 
						|
 | 
						|
    for fixed in 0..16 {
 | 
						|
        let style = style(fixed, args.layer, args.effects);
 | 
						|
        let _ = print_number(&mut stdout, fixed, style);
 | 
						|
        if fixed == 7 || fixed == 15 {
 | 
						|
            let _ = stdout.write_colored(None, None, &b"\n"[..]);
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    for r in 0..6 {
 | 
						|
        let _ = stdout.write_colored(None, None, &b"\n"[..]);
 | 
						|
        for g in 0..6 {
 | 
						|
            for b in 0..6 {
 | 
						|
                let fixed = r * 36 + g * 6 + b + 16;
 | 
						|
                let style = style(fixed, args.layer, args.effects);
 | 
						|
                let _ = print_number(&mut stdout, fixed, style);
 | 
						|
            }
 | 
						|
            let _ = stdout.write_colored(None, None, &b"\n"[..]);
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    for c in 0..24 {
 | 
						|
        if 0 == c % 8 {
 | 
						|
            let _ = stdout.write_colored(None, None, &b"\n"[..]);
 | 
						|
        }
 | 
						|
        let fixed = 232 + c;
 | 
						|
        let style = style(fixed, args.layer, args.effects);
 | 
						|
        let _ = print_number(&mut stdout, fixed, style);
 | 
						|
    }
 | 
						|
 | 
						|
    Ok(())
 | 
						|
}
 | 
						|
 | 
						|
fn style(fixed: u8, layer: Layer, effects: anstyle::Effects) -> anstyle::Style {
 | 
						|
    let color = anstyle::Ansi256Color(fixed).into();
 | 
						|
    (match layer {
 | 
						|
        Layer::Fg => anstyle::Style::new().fg_color(Some(color)),
 | 
						|
        Layer::Bg => anstyle::Style::new().bg_color(Some(color)),
 | 
						|
        Layer::Underline => anstyle::Style::new().underline_color(Some(color)),
 | 
						|
    }) | effects
 | 
						|
}
 | 
						|
 | 
						|
fn print_number(
 | 
						|
    stdout: &mut std::io::StdoutLock<'static>,
 | 
						|
    fixed: u8,
 | 
						|
    style: anstyle::Style,
 | 
						|
) -> std::io::Result<()> {
 | 
						|
    let fg = style.get_fg_color().and_then(|c| match c {
 | 
						|
        anstyle::Color::Ansi(c) => Some(c),
 | 
						|
        anstyle::Color::Ansi256(c) => c.into_ansi(),
 | 
						|
        anstyle::Color::Rgb(_) => None,
 | 
						|
    });
 | 
						|
    let bg = style.get_bg_color().and_then(|c| match c {
 | 
						|
        anstyle::Color::Ansi(c) => Some(c),
 | 
						|
        anstyle::Color::Ansi256(c) => c.into_ansi(),
 | 
						|
        anstyle::Color::Rgb(_) => None,
 | 
						|
    });
 | 
						|
 | 
						|
    stdout
 | 
						|
        .write_colored(fg, bg, format!("{:>4}", fixed).as_bytes())
 | 
						|
        .map(|_| ())
 | 
						|
}
 | 
						|
 | 
						|
#[derive(Default)]
 | 
						|
struct Args {
 | 
						|
    effects: anstyle::Effects,
 | 
						|
    layer: Layer,
 | 
						|
}
 | 
						|
 | 
						|
#[derive(Copy, Clone, Default)]
 | 
						|
enum Layer {
 | 
						|
    #[default]
 | 
						|
    Fg,
 | 
						|
    Bg,
 | 
						|
    Underline,
 | 
						|
}
 | 
						|
 | 
						|
impl Args {
 | 
						|
    fn parse() -> Result<Self, lexopt::Error> {
 | 
						|
        use lexopt::prelude::*;
 | 
						|
 | 
						|
        let mut res = Args::default();
 | 
						|
 | 
						|
        let mut args = lexopt::Parser::from_env();
 | 
						|
        while let Some(arg) = args.next()? {
 | 
						|
            match arg {
 | 
						|
                Long("layer") => {
 | 
						|
                    res.layer = args.value()?.parse_with(|s| match s {
 | 
						|
                        "fg" => Ok(Layer::Fg),
 | 
						|
                        "bg" => Ok(Layer::Bg),
 | 
						|
                        "underline" => Ok(Layer::Underline),
 | 
						|
                        _ => Err("expected values fg, bg, underline"),
 | 
						|
                    })?;
 | 
						|
                }
 | 
						|
                Long("effect") => {
 | 
						|
                    const EFFECTS: [(&str, anstyle::Effects); 12] = [
 | 
						|
                        ("bold", anstyle::Effects::BOLD),
 | 
						|
                        ("dimmed", anstyle::Effects::DIMMED),
 | 
						|
                        ("italic", anstyle::Effects::ITALIC),
 | 
						|
                        ("underline", anstyle::Effects::UNDERLINE),
 | 
						|
                        ("double_underline", anstyle::Effects::UNDERLINE),
 | 
						|
                        ("curly_underline", anstyle::Effects::CURLY_UNDERLINE),
 | 
						|
                        ("dotted_underline", anstyle::Effects::DOTTED_UNDERLINE),
 | 
						|
                        ("dashed_underline", anstyle::Effects::DASHED_UNDERLINE),
 | 
						|
                        ("blink", anstyle::Effects::BLINK),
 | 
						|
                        ("invert", anstyle::Effects::INVERT),
 | 
						|
                        ("hidden", anstyle::Effects::HIDDEN),
 | 
						|
                        ("strikethrough", anstyle::Effects::STRIKETHROUGH),
 | 
						|
                    ];
 | 
						|
                    let effect = args.value()?.parse_with(|s| {
 | 
						|
                        EFFECTS
 | 
						|
                            .into_iter()
 | 
						|
                            .find(|(name, _)| *name == s)
 | 
						|
                            .map(|(_, effect)| effect)
 | 
						|
                            .ok_or_else(|| {
 | 
						|
                                format!(
 | 
						|
                                    "expected one of {}",
 | 
						|
                                    EFFECTS
 | 
						|
                                        .into_iter()
 | 
						|
                                        .map(|(n, _)| n)
 | 
						|
                                        .collect::<Vec<_>>()
 | 
						|
                                        .join(", ")
 | 
						|
                                )
 | 
						|
                            })
 | 
						|
                    })?;
 | 
						|
                    res.effects = res.effects.insert(effect);
 | 
						|
                }
 | 
						|
                _ => return Err(arg.unexpected()),
 | 
						|
            }
 | 
						|
        }
 | 
						|
        Ok(res)
 | 
						|
    }
 | 
						|
}
 |