This commit is contained in:
ldlda committed 2025-01-08 03:59:32 +07:00
commit eaf7361cb8
8 files changed
+323

No files matched your search

+1
View File
@@ -0,0 +1 @@
/target
+6
View File
@@ -0,0 +1,6 @@
[package]
name = "lda_ansi"
version = "0.0.1"
edition = "2021"
[dependencies]
+18
View File
@@ -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"),
}
}
}
+13
View File
@@ -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],
}
}
}
+155
View File
@@ -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]
);
}
}
+95
View File
@@ -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
View File
@@ -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
}
}
+5
View File
@@ -0,0 +1,5 @@
use lda_ansi::ansi_colors::Color;
fn main(){
}