67 lines
1.4 KiB
Rust
67 lines
1.4 KiB
Rust
#![no_std]
|
|
|
|
use winnow::Result;
|
|
use winnow::ascii::dec_uint;
|
|
use winnow::combinator::{alt, preceded, seq};
|
|
use winnow::error::ContextError;
|
|
use winnow::prelude::*;
|
|
|
|
pub enum AnsiiEscape {
|
|
Color16(ColorPlace, Color16Type, u8),
|
|
Color256(u8),
|
|
ColorRGB(ColorPlace, u8, u8, u8),
|
|
}
|
|
pub enum ColorPlace {
|
|
Foreground,
|
|
Background,
|
|
}
|
|
pub enum Color16Type {
|
|
Normal,
|
|
Bold,
|
|
Brigth,
|
|
}
|
|
|
|
fn parse_color16(input: &mut &str) -> Result<AnsiiEscape> {
|
|
let (c, _) = preceded("[", seq!(dec_uint, "m")).parse_next(input)?;
|
|
if c < 30 || c == 38 || c == 48 || c > 49 {
|
|
Err(ContextError::new())
|
|
} else {
|
|
Ok(AnsiiEscape::Color16(
|
|
ColorPlace::Foreground,
|
|
Color16Type::Normal,
|
|
c,
|
|
))
|
|
}
|
|
}
|
|
|
|
fn parse_color_rgb(input: &mut &str) -> Result<AnsiiEscape> {
|
|
let (t, _, r, _, g, _, b, _) = preceded(
|
|
"[",
|
|
seq!(
|
|
alt(("38", "48")),
|
|
";",
|
|
dec_uint,
|
|
";",
|
|
dec_uint,
|
|
";",
|
|
dec_uint,
|
|
"m"
|
|
),
|
|
)
|
|
.parse_next(input)?;
|
|
Ok(AnsiiEscape::ColorRGB(
|
|
if t == "38" {
|
|
ColorPlace::Foreground
|
|
} else {
|
|
ColorPlace::Background
|
|
},
|
|
r,
|
|
g,
|
|
b,
|
|
))
|
|
}
|
|
|
|
pub fn parse_ansii(input: &mut &str) -> Result<AnsiiEscape> {
|
|
alt((parse_color_rgb, parse_color16)).parse_next(input)
|
|
}
|