not ok
This commit is contained in:
commit
eaf7361cb8
8 files changed
+323
No files matched your search
@@ -0,0 +1 @@
|
|||||||
|
/target
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
[package]
|
||||||
|
name = "lda_ansi"
|
||||||
|
version = "0.0.1"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
use std::fmt::{Debug, Display};
|
||||||
|
|
||||||
|
use super::Color;
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum ColorError {
|
||||||
|
NoCode,
|
||||||
|
InvalidCode(u8), // 50 for example which is for other things
|
||||||
|
InvalidMode, // not 2 or 5, or 5 but 3 element
|
||||||
|
}
|
||||||
|
impl Display for ColorError {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
match self {
|
||||||
|
ColorError::NoCode => write!(f, "No color code found"),
|
||||||
|
ColorError::InvalidCode(code) => write!(f, "Invalid color code: {}", code),
|
||||||
|
ColorError::InvalidMode => write!(f, "Invalid color mode"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
// i hate when other places use this construct (58, rarely
|
||||||
|
pub enum CustomColor {
|
||||||
|
Color256(u8),
|
||||||
|
TrueColor(u8, u8, u8),
|
||||||
|
}
|
||||||
|
impl From<CustomColor> for Vec<u8> {
|
||||||
|
fn from(value: CustomColor) -> Self {
|
||||||
|
match value {
|
||||||
|
CustomColor::Color256(v) => vec![5, v],
|
||||||
|
CustomColor::TrueColor(r, g, b) => vec![2, r, g, b],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,155 @@
|
|||||||
|
pub mod color_error;
|
||||||
|
pub mod custom_color; // why
|
||||||
|
use color_error::ColorError;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct Color {
|
||||||
|
inner: Vec<u8>,
|
||||||
|
}
|
||||||
|
|
||||||
|
// impl TryFrom<Color> for Vec<u8> {
|
||||||
|
// type Error = ColorError;
|
||||||
|
// fn try_from(value: Color) -> Result<Self, Self::Error> {
|
||||||
|
// value.codes()
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
impl From<Color> for Vec<u8> {
|
||||||
|
fn from(value: Color) -> Self {
|
||||||
|
value.codes()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// impl TryFrom<&Color> for Vec<u8> {
|
||||||
|
// type Error = ColorError;
|
||||||
|
// fn try_from(value: &Color) -> Result<Self, Self::Error> {
|
||||||
|
// value.codes()
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// impl TryFrom<&mut Color> for Vec<u8> {
|
||||||
|
// type Error = ColorError;
|
||||||
|
// fn try_from(value: &mut Color) -> Result<Self, Self::Error> {
|
||||||
|
// value.codes()
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
macro_rules! color_defintion {
|
||||||
|
($name:ident, $code:expr) => {
|
||||||
|
fn $name() -> Color {
|
||||||
|
Color {inner: vec![$code]}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
($name:ident, $code:expr, $mode:expr, ($($param:ident),+)) => {
|
||||||
|
fn $name($($param: u8),+) -> Color {
|
||||||
|
Color {inner: vec![$code, $mode, $($param), +]}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Color {
|
||||||
|
color_defintion!(default, 39);
|
||||||
|
}
|
||||||
|
type ColorResult<T> = Result<T, ColorError>;
|
||||||
|
|
||||||
|
impl Color {
|
||||||
|
color_defintion!(black, 30); // also can be vec![38, 5, 0] for
|
||||||
|
// some ass fucking reason
|
||||||
|
color_defintion!(red, 31);
|
||||||
|
color_defintion!(green, 32);
|
||||||
|
color_defintion!(yellow, 33);
|
||||||
|
color_defintion!(blue, 34);
|
||||||
|
color_defintion!(magenta, 35);
|
||||||
|
color_defintion!(cyan, 36);
|
||||||
|
color_defintion!(white, 37);
|
||||||
|
color_defintion!(custom_256, 38, 5, (value));
|
||||||
|
color_defintion!(custom_truecolor, 38, 2, (r, g, b));
|
||||||
|
|
||||||
|
fn codes(&self) -> Vec<u8> {
|
||||||
|
// Result<Vec<u8>, ColorError> {
|
||||||
|
debug_assert!(self.validate_mode().is_ok(), "Invalid color mode");
|
||||||
|
self.inner.to_vec()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bg(mut self) -> Self {
|
||||||
|
// ColorResult<Self> {
|
||||||
|
// this is why inner is private
|
||||||
|
let code = self.inner.first_mut()
|
||||||
|
.unwrap();
|
||||||
|
// .ok_or(ColorError::NoCode)?;
|
||||||
|
|
||||||
|
*code = match code {
|
||||||
|
30..=39 | 90..=99 => *code + 10,
|
||||||
|
40..=49 | 100..=109 => *code,
|
||||||
|
// _ => return Err(ColorError::InvalidCode(*code)),
|
||||||
|
_ => unreachable!(),
|
||||||
|
};
|
||||||
|
|
||||||
|
// Ok(self)
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fg(mut self) -> Self {
|
||||||
|
// -> ColorResult<Self> {
|
||||||
|
// this is why inner is private
|
||||||
|
let code = self.inner.first_mut().unwrap();
|
||||||
|
// .ok_or(ColorError::NoCode)?;
|
||||||
|
|
||||||
|
*code = match code {
|
||||||
|
30..=39 | 90..=99 => *code,
|
||||||
|
40..=49 | 100..=109 => *code + 10,
|
||||||
|
_ => unreachable!()
|
||||||
|
// return Err(ColorError::InvalidCode(*code)),
|
||||||
|
};
|
||||||
|
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bright(mut self) -> Self {
|
||||||
|
// this is why inner is private
|
||||||
|
let code = self.inner.first_mut().unwrap();
|
||||||
|
// .ok_or(ColorError::NoCode)?;
|
||||||
|
|
||||||
|
*code = match code {
|
||||||
|
30..=49 => *code + (90 - 30),
|
||||||
|
90..=109 => *code,
|
||||||
|
_ => unreachable!(),
|
||||||
|
// return Err(ColorError::InvalidCode(*code)),
|
||||||
|
};
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
|
fn validate_mode(&self) -> ColorResult<()> {
|
||||||
|
if self.inner.len() < 2 {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
match self.inner[1] {
|
||||||
|
2 if self.inner.len() != 5 => Err(ColorError::InvalidMode),
|
||||||
|
5 if self.inner.len() != 3 => Err(ColorError::InvalidMode),
|
||||||
|
2 | 5 => Ok(()),
|
||||||
|
_ => Err(ColorError::InvalidMode),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
#[test]
|
||||||
|
fn test_to_vec() {
|
||||||
|
let red_bg = Color::red().bg();
|
||||||
|
let blue_text = Color::blue();
|
||||||
|
let custom_green = Color::custom_truecolor(0x74, 0xb7, 0x2e)
|
||||||
|
.bg();
|
||||||
|
assert_eq!(Vec::<u8>::from(red_bg), vec![41]);
|
||||||
|
assert_eq!(Vec::<u8>::from(blue_text), vec![34]);
|
||||||
|
assert_eq!(
|
||||||
|
Vec::<u8>::from(custom_green),
|
||||||
|
vec![48, 2, 0x74, 0xb7, 0x2e]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,95 @@
|
|||||||
|
use std::ops::{Deref, Mul, MulAssign, Neg, Not, Sub, SubAssign};
|
||||||
|
|
||||||
|
pub enum Style {
|
||||||
|
Reset,
|
||||||
|
Bold,
|
||||||
|
Faint,
|
||||||
|
Italic,
|
||||||
|
Underline,
|
||||||
|
BlinkSlow,
|
||||||
|
BlinkFast,
|
||||||
|
SwapColor,
|
||||||
|
Strike,
|
||||||
|
Hide,
|
||||||
|
//
|
||||||
|
NormalWeight,
|
||||||
|
Straight,
|
||||||
|
Static,
|
||||||
|
NoUnderline,
|
||||||
|
NormalColor,
|
||||||
|
NoStrike,
|
||||||
|
Reveal,
|
||||||
|
}
|
||||||
|
impl Style {
|
||||||
|
pub fn code(&self) -> u8 {
|
||||||
|
use Style::*;
|
||||||
|
match self {
|
||||||
|
Reset => 0,
|
||||||
|
Bold => 1,
|
||||||
|
Faint => 2,
|
||||||
|
Italic => 3,
|
||||||
|
Underline => 4,
|
||||||
|
BlinkSlow => 5,
|
||||||
|
BlinkFast => 6,
|
||||||
|
SwapColor => 7,
|
||||||
|
Strike => 9,
|
||||||
|
Hide => 8,
|
||||||
|
NormalWeight => 22,
|
||||||
|
Straight => 23,
|
||||||
|
NoUnderline => 24,
|
||||||
|
Static => 25,
|
||||||
|
NormalColor => 27,
|
||||||
|
NoStrike => 29,
|
||||||
|
Reveal => 28,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Not for Style {
|
||||||
|
type Output = Self;
|
||||||
|
fn not(self) -> Self::Output {
|
||||||
|
use Style::*;
|
||||||
|
match self {
|
||||||
|
Bold => NormalWeight,
|
||||||
|
Faint => NormalWeight,
|
||||||
|
Italic => Straight,
|
||||||
|
Underline => NoUnderline,
|
||||||
|
BlinkSlow => Static,
|
||||||
|
BlinkFast => Static,
|
||||||
|
SwapColor => NormalColor,
|
||||||
|
Strike => NoStrike,
|
||||||
|
Hide => Reveal,
|
||||||
|
_ => Reset, // am i cooked
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Neg for Style {
|
||||||
|
type Output = Self;
|
||||||
|
fn neg(self) -> Self::Output {
|
||||||
|
use Style::*;
|
||||||
|
match self {
|
||||||
|
Bold => Faint,
|
||||||
|
Faint => Bold,
|
||||||
|
|
||||||
|
// Style opposites
|
||||||
|
Italic => Straight,
|
||||||
|
Underline => NoUnderline,
|
||||||
|
BlinkSlow | BlinkFast => Static,
|
||||||
|
SwapColor => NormalColor,
|
||||||
|
Strike => NoStrike,
|
||||||
|
Hide => Reveal,
|
||||||
|
|
||||||
|
_ => self,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_style_negation() {
|
||||||
|
assert!(matches!(-Style::Bold, Style::Faint));
|
||||||
|
assert!(matches!(-Style::Faint, Style::Bold));
|
||||||
|
assert!(matches!(-(-Style::Bold), Style::Bold));
|
||||||
|
}
|
||||||
|
}
|
||||||
+30
@@ -0,0 +1,30 @@
|
|||||||
|
#![allow(unused)]
|
||||||
|
|
||||||
|
use ansi_colors::Color;
|
||||||
|
pub mod ansi_colors;
|
||||||
|
mod ansi_styles; // here so ide dont dim code
|
||||||
|
use ansi_styles::Style as AnsiStyle;
|
||||||
|
struct AnsiCodes {
|
||||||
|
prefix: String,
|
||||||
|
suffix: String,
|
||||||
|
codes: Vec<u8>,
|
||||||
|
}
|
||||||
|
struct Style {
|
||||||
|
inner: Vec<u8>,
|
||||||
|
}
|
||||||
|
trait StyleTrait {
|
||||||
|
|
||||||
|
}
|
||||||
|
struct AnsiStyles {
|
||||||
|
text: String,
|
||||||
|
styles: Vec<Style>, // no
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Style {
|
||||||
|
fn color(&mut self, color: Color) -> &mut Self {
|
||||||
|
self.inner.append(&mut color.try_into().expect("oof")); self // does this clear color.inner?
|
||||||
|
}
|
||||||
|
fn style(&mut self, style: AnsiStyle) -> &mut Self {
|
||||||
|
self.inner.push(style.code()); self
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
use lda_ansi::ansi_colors::Color;
|
||||||
|
|
||||||
|
|
||||||
|
fn main(){
|
||||||
|
}
|
||||||
Reference in new issue
Block a user