From 9cf7b1e731163f9eaee94b9a74c6ca77ed9d7968 Mon Sep 17 00:00:00 2001 From: syaw0 Date: Tue, 29 Oct 2024 09:46:29 +0330 Subject: [PATCH 01/51] feat: initialize new Rust project with cargo init --- .gitignore | 13 +++---------- Cargo.lock | 7 +++++++ Cargo.toml | 6 ++++++ src/lib.rs | 14 ++++++++++++++ src/main.rs | 3 +++ 5 files changed, 33 insertions(+), 10 deletions(-) create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100644 src/lib.rs create mode 100644 src/main.rs diff --git a/.gitignore b/.gitignore index d01bd1a..fdef129 100644 --- a/.gitignore +++ b/.gitignore @@ -3,19 +3,12 @@ debug/ target/ -# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries -# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html -Cargo.lock - # These are backup files generated by rustfmt **/*.rs.bk # MSVC Windows builds of rustc generate these, which store debugging information *.pdb -# RustRover -# JetBrains specific template is maintained in a separate JetBrains.gitignore that can -# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore -# and can be added to the global gitignore or merged into this file. For a more nuclear -# option (not recommended) you can uncomment the following to ignore the entire idea folder. -#.idea/ \ No newline at end of file +# Added by cargo + +/target diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..501903c --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "Vitalux" +version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..e77840f --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "Vitalux" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..7d12d9a --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,14 @@ +pub fn add(left: usize, right: usize) -> usize { + left + right +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn it_works() { + let result = add(2, 2); + assert_eq!(result, 4); + } +} diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..6965c96 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("Hello I'm Vitalux!") +} From 8cd25aa8c6f2785906e7cac78af905f73eab3f61 Mon Sep 17 00:00:00 2001 From: syaw0 Date: Tue, 29 Oct 2024 09:47:53 +0330 Subject: [PATCH 02/51] chore: update Cargo.toml project metadata --- Cargo.toml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Cargo.toml b/Cargo.toml index e77840f..44387e4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,5 +2,12 @@ name = "Vitalux" version = "0.1.0" edition = "2021" +description = "Colorize Your Terminal with Vitalux: A Rust-powered Formatting Tool" +authors = ["Siavash Siamhb7@protonmail.com"] +homepage = "https://crates.io/crates/vitalux" +repository = "https://github.com/Syaw0/Vitalux" +license-file = "./LICENSE" +keywords = ["cli","terminal","rust","tool","coloize","formatter"] +categories = ["terminal","cli","command-line-utilitise"] [dependencies] From d67a238ad0fa16400554eb8005ceaf300122526a Mon Sep 17 00:00:00 2001 From: syaw0 Date: Tue, 29 Oct 2024 10:46:25 +0330 Subject: [PATCH 03/51] chore: add Github Actions workflow file --- .github/workflows/rust.yml | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 .github/workflows/rust.yml diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml new file mode 100644 index 0000000..41b5d73 --- /dev/null +++ b/.github/workflows/rust.yml @@ -0,0 +1,21 @@ +name: Rust + +on: + push: + branches: ["develop"] + pull_request: + branches: ["develop"] + +env: + CARGO_TERM_COLOR: always + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + - name: Build + run: cargo build --verbose + - name: Run tests + run: cargo test --verbose From 636763806667b1684719c44e13aba41ea771bde9 Mon Sep 17 00:00:00 2001 From: syaw0 Date: Thu, 31 Oct 2024 10:06:42 +0330 Subject: [PATCH 04/51] feat: Add ANSIEscapeCode struct with accompanying tests this struct like a placeholder to hold a ansi code and act like abstraction --- src/lib.rs | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 7d12d9a..c9f2206 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,14 +1,29 @@ -pub fn add(left: usize, right: usize) -> usize { - left + right +struct ANSIEscapeCode { + parameter: String, +} +impl ANSIEscapeCode { + fn new(parameter: String) -> Self { + ANSIEscapeCode { parameter } + } + + fn code(&self) -> String { + format!("\\x1b[{}m", self.parameter) + } } #[cfg(test)] -mod tests { +mod test { use super::*; #[test] - fn it_works() { - let result = add(2, 2); - assert_eq!(result, 4); + fn create_simple_ansi_code() { + let p = ANSIEscapeCode::new(String::from("33")); + assert_eq!(p.code(), "\\x1b[33m") + } + + #[test] + fn create_reset_ansi_code() { + let reset_ansi = ANSIEscapeCode::new(String::from("0")); + assert_eq!("\\x1b[0m", reset_ansi.code()); } } From d63eee20ec1321167b24f471c6f1fe13241511d9 Mon Sep 17 00:00:00 2001 From: syaw0 Date: Fri, 1 Nov 2024 08:12:46 +0330 Subject: [PATCH 05/51] refactor: move ANSIEscapeCode and tests to own module --- src/ansi_escape_code.rs | 12 ++++++++++++ src/lib.rs | 30 ++---------------------------- src/test.rs | 23 +++++++++++++++++++++++ 3 files changed, 37 insertions(+), 28 deletions(-) create mode 100644 src/ansi_escape_code.rs create mode 100644 src/test.rs diff --git a/src/ansi_escape_code.rs b/src/ansi_escape_code.rs new file mode 100644 index 0000000..7dbde5d --- /dev/null +++ b/src/ansi_escape_code.rs @@ -0,0 +1,12 @@ +pub struct ANSIEscapeCode { + parameter: String, +} +impl ANSIEscapeCode { + pub fn new(parameter: String) -> Self { + ANSIEscapeCode { parameter } + } + + pub fn code(&self) -> String { + format!("\\x1b[{}m", self.parameter) + } +} diff --git a/src/lib.rs b/src/lib.rs index c9f2206..94e231c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,29 +1,3 @@ -struct ANSIEscapeCode { - parameter: String, -} -impl ANSIEscapeCode { - fn new(parameter: String) -> Self { - ANSIEscapeCode { parameter } - } +mod ansi_escape_code; - fn code(&self) -> String { - format!("\\x1b[{}m", self.parameter) - } -} - -#[cfg(test)] -mod test { - use super::*; - - #[test] - fn create_simple_ansi_code() { - let p = ANSIEscapeCode::new(String::from("33")); - assert_eq!(p.code(), "\\x1b[33m") - } - - #[test] - fn create_reset_ansi_code() { - let reset_ansi = ANSIEscapeCode::new(String::from("0")); - assert_eq!("\\x1b[0m", reset_ansi.code()); - } -} +// ======================================================================= diff --git a/src/test.rs b/src/test.rs new file mode 100644 index 0000000..2fc6eaa --- /dev/null +++ b/src/test.rs @@ -0,0 +1,23 @@ +#[cfg(test)] +mod ansi_escape_code_test { + use crate::ansi_escape_code::ANSIEscapeCode; + use super::*; + + #[test] + fn create_simple_ansi_code() { + let p = ANSIEscapeCode::new(String::from("33")); + assert_eq!(p.code(), "\\x1b[33m") + } + + #[test] + fn create_reset_ansi_code() { + let reset_ansi = ANSIEscapeCode::new(String::from("0")); + assert_eq!("\\x1b[0m", reset_ansi.code()); + } + + #[test] + fn create_bright_cyan_ansi_code() { + let reset_ansi = ANSIEscapeCode::new(String::from("96")); + assert_eq!("\\x1b[96m", reset_ansi.code()); + } +} From 27dc04f7e6198266b26bfd920ef64b5d8d177e88 Mon Sep 17 00:00:00 2001 From: syaw0 Date: Fri, 1 Nov 2024 08:40:08 +0330 Subject: [PATCH 06/51] feat: Add basic colors constants these color are a 3/4 bit colors and include 16 color for each foreground and background. --- src/colors.rs | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 src/colors.rs diff --git a/src/colors.rs b/src/colors.rs new file mode 100644 index 0000000..412b8a3 --- /dev/null +++ b/src/colors.rs @@ -0,0 +1,40 @@ +pub struct BasicColor { + pub fg: u8, + pub bg: u8, +} + +pub const BLACK: BasicColor = BasicColor { fg: 30, bg: 40 }; +pub const RED: BasicColor = BasicColor { fg: 31, bg: 41 }; +pub const GREEN: BasicColor = BasicColor { fg: 32, bg: 42 }; +pub const YELLOW: BasicColor = BasicColor { fg: 33, bg: 43 }; +pub const BLUE: BasicColor = BasicColor { fg: 34, bg: 44 }; +pub const MAGENTA: BasicColor = BasicColor { fg: 35, bg: 45 }; +pub const CYAN: BasicColor = BasicColor { fg: 36, bg: 46 }; +pub const WHITE: BasicColor = BasicColor { fg: 37, bg: 47 }; +pub const GRAY: BasicColor = BasicColor { fg: 90, bg: 10 }; +pub const BRIGHT_RED: BasicColor = BasicColor { fg: 91, bg: 101 }; +pub const BRIGHT_GREEN: BasicColor = BasicColor { fg: 92, bg: 102 }; +pub const BRIGHT_YELLOW: BasicColor = BasicColor { fg: 93, bg: 103 }; +pub const BRIGHT_BLUE: BasicColor = BasicColor { fg: 94, bg: 104 }; +pub const BRIGHT_MAGENTA: BasicColor = BasicColor { fg: 95, bg: 105 }; +pub const BRIGHT_CYAN: BasicColor = BasicColor { fg: 96, bg: 106 }; +pub const BRIGHT_WHITE: BasicColor = BasicColor { fg: 97, bg: 107 }; + +// ======================================================================= + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn black_colors() { + assert_eq!(30, BLACK.fg); + assert_eq!(40, BLACK.bg) + } + + #[test] + fn cyan_colors() { + assert_eq!(36, CYAN.fg); + assert_eq!(46, CYAN.bg) + } +} From 5adde3cc897a2d5a2046185e439868854b3fded2 Mon Sep 17 00:00:00 2001 From: syaw0 Date: Fri, 1 Nov 2024 08:46:13 +0330 Subject: [PATCH 07/51] feat: Add palette color struct with tests --- src/colors.rs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/colors.rs b/src/colors.rs index 412b8a3..34ebbd9 100644 --- a/src/colors.rs +++ b/src/colors.rs @@ -20,6 +20,12 @@ pub const BRIGHT_MAGENTA: BasicColor = BasicColor { fg: 95, bg: 105 }; pub const BRIGHT_CYAN: BasicColor = BasicColor { fg: 96, bg: 106 }; pub const BRIGHT_WHITE: BasicColor = BasicColor { fg: 97, bg: 107 }; +// + +pub struct PaletteColor { + pub index: u8, +} + // ======================================================================= #[cfg(test)] @@ -37,4 +43,16 @@ mod test { assert_eq!(36, CYAN.fg); assert_eq!(46, CYAN.bg) } + + #[test] + fn black_palette_color() { + let standard_black = PaletteColor { index: 0 }; + assert_eq!(0, standard_black.index) + } + + #[test] + fn _palette_color() { + let gray_scale = PaletteColor { index: 243 }; + assert_eq!(243, gray_scale.index) + } } From 8b244552401c3856d1cc37f69d2002bb2a1860d3 Mon Sep 17 00:00:00 2001 From: syaw0 Date: Fri, 1 Nov 2024 08:51:14 +0330 Subject: [PATCH 08/51] feat: Add RGB struct with tests --- src/colors.rs | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/src/colors.rs b/src/colors.rs index 34ebbd9..5837592 100644 --- a/src/colors.rs +++ b/src/colors.rs @@ -1,6 +1,6 @@ pub struct BasicColor { - pub fg: u8, - pub bg: u8, + fg: u8, + bg: u8, } pub const BLACK: BasicColor = BasicColor { fg: 30, bg: 40 }; @@ -23,7 +23,13 @@ pub const BRIGHT_WHITE: BasicColor = BasicColor { fg: 97, bg: 107 }; // pub struct PaletteColor { - pub index: u8, + index: u8, +} + +pub struct RGB { + r: u8, + g: u8, + b: u8, } // ======================================================================= @@ -51,8 +57,24 @@ mod test { } #[test] - fn _palette_color() { + fn gray_scale_palette_color() { let gray_scale = PaletteColor { index: 243 }; assert_eq!(243, gray_scale.index) } + + #[test] + fn red_rgb_color() { + let red = RGB { r: 255, g: 0, b: 0 }; + assert_eq!(255, red.r); + assert_eq!(0, red.g); + assert_eq!(0, red.b) + } + + #[test] + fn salmon_rgb_color() { + let salmon = RGB { r: 250, g: 128, b: 114 }; + assert_eq!(250, salmon.r); + assert_eq!(128, salmon.g); + assert_eq!(114, salmon.b) + } } From 5b24cdee105e46dc5a9d56466d3f25672dc9dcae Mon Sep 17 00:00:00 2001 From: syaw0 Date: Fri, 1 Nov 2024 09:09:10 +0330 Subject: [PATCH 09/51] feat: Add Colorify trait with paint_fg and paint_bg this way we implement this trait for all colors and make a customized behaviour on each color system and get the foreground and background color code. --- src/colors.rs | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/src/colors.rs b/src/colors.rs index 5837592..ea6e8e2 100644 --- a/src/colors.rs +++ b/src/colors.rs @@ -1,8 +1,23 @@ +trait Colorify { + fn paint_fg(&self) -> String; + fn paint_bg(&self) -> String; +} + pub struct BasicColor { fg: u8, bg: u8, } +impl Colorify for BasicColor { + fn paint_bg(&self) -> String { + format!("{}", self.bg) + } + + fn paint_fg(&self) -> String { + format!("{}", self.fg) + } +} + pub const BLACK: BasicColor = BasicColor { fg: 30, bg: 40 }; pub const RED: BasicColor = BasicColor { fg: 31, bg: 41 }; pub const GREEN: BasicColor = BasicColor { fg: 32, bg: 42 }; @@ -26,12 +41,30 @@ pub struct PaletteColor { index: u8, } +impl Colorify for PaletteColor { + fn paint_bg(&self) -> String { + format!("48;5;{}", self.index) + } + fn paint_fg(&self) -> String { + format!("38;5;{}", self.index) + } +} + pub struct RGB { r: u8, g: u8, b: u8, } +impl Colorify for RGB { + fn paint_bg(&self) -> String { + format!("48;2;{};{};{}", self.r, self.g, self.b) + } + fn paint_fg(&self) -> String { + format!("38;2;{};{};{}", self.r, self.g, self.b) + } +} + // ======================================================================= #[cfg(test)] @@ -50,6 +83,20 @@ mod test { assert_eq!(46, CYAN.bg) } + #[test] + fn paint_yellow_foreground() { + let painted_fg = YELLOW.paint_fg(); + + assert_eq!("33", painted_fg) + } + + #[test] + fn paint_magenta_background() { + let painted_bg = MAGENTA.paint_bg(); + + assert_eq!("45", painted_bg) + } + #[test] fn black_palette_color() { let standard_black = PaletteColor { index: 0 }; @@ -62,6 +109,20 @@ mod test { assert_eq!(243, gray_scale.index) } + #[test] + fn palette_paint_green_fg() { + let green = PaletteColor { index: 118 }; + let painted_fg = green.paint_fg(); + assert_eq!("38;5;118", painted_fg) + } + + #[test] + fn palette_paint_blue_bg() { + let blue = PaletteColor { index: 33 }; + let painted_bg = blue.paint_bg(); + assert_eq!("48;5;33", painted_bg) + } + #[test] fn red_rgb_color() { let red = RGB { r: 255, g: 0, b: 0 }; @@ -77,4 +138,18 @@ mod test { assert_eq!(128, salmon.g); assert_eq!(114, salmon.b) } + + #[test] + fn rgb_paint_purple_fg() { + let purple = RGB { r: 126, g: 50, b: 219 }; + let painted_fg = purple.paint_fg(); + assert_eq!("38;2;126;50;219", painted_fg) + } + + #[test] + fn rgb_paint_orange_bg() { + let orange = RGB { r: 219, g: 132, b: 50 }; + let painted_bg = orange.paint_bg(); + assert_eq!("48;2;219;132;50", painted_bg) + } } From 5c669e64bf22b1d4a486cd7d0e90fd548a4ed640 Mon Sep 17 00:00:00 2001 From: syaw0 Date: Fri, 1 Nov 2024 09:50:00 +0330 Subject: [PATCH 10/51] feat: Add a new trait, `Stylify` that use just `make_styles` in this way we can use only one method to implement between `colors` and `formatter` --- src/colors.rs | 73 +++++++++++++++++++++++++++++++-------------------- 1 file changed, 45 insertions(+), 28 deletions(-) diff --git a/src/colors.rs b/src/colors.rs index ea6e8e2..e853640 100644 --- a/src/colors.rs +++ b/src/colors.rs @@ -1,6 +1,10 @@ -trait Colorify { - fn paint_fg(&self) -> String; - fn paint_bg(&self) -> String; +pub enum PaintType { + FG, + BG, +} + +pub trait Stylify { + fn make_styles(&self, paint_type: Option) -> String; } pub struct BasicColor { @@ -8,13 +12,14 @@ pub struct BasicColor { bg: u8, } -impl Colorify for BasicColor { - fn paint_bg(&self) -> String { - format!("{}", self.bg) - } - - fn paint_fg(&self) -> String { - format!("{}", self.fg) +impl Stylify for BasicColor { + /// If the `is_foreground` was None it's assume as foreground + fn make_styles(&self, paint_type: Option) -> String { + let paint_type = paint_type.unwrap_or(PaintType::FG); + format!("{}", match paint_type { + PaintType::FG => self.fg, + PaintType::BG => self.bg, + }) } } @@ -41,12 +46,17 @@ pub struct PaletteColor { index: u8, } -impl Colorify for PaletteColor { - fn paint_bg(&self) -> String { - format!("48;5;{}", self.index) - } - fn paint_fg(&self) -> String { - format!("38;5;{}", self.index) +impl Stylify for PaletteColor { + fn make_styles(&self, paint_type: Option) -> String { + let paint_type = paint_type.unwrap_or(PaintType::FG); + format!( + "{};5;{}", + match paint_type { + PaintType::FG => "38", + PaintType::BG => "48", + }, + self.index + ) } } @@ -56,12 +66,19 @@ pub struct RGB { b: u8, } -impl Colorify for RGB { - fn paint_bg(&self) -> String { - format!("48;2;{};{};{}", self.r, self.g, self.b) - } - fn paint_fg(&self) -> String { - format!("38;2;{};{};{}", self.r, self.g, self.b) +impl Stylify for RGB { + fn make_styles(&self, paint_type: Option) -> String { + let paint_type = paint_type.unwrap_or(PaintType::FG); + format!( + "{};2;{};{};{}", + match paint_type { + PaintType::FG => "38", + PaintType::BG => "48", + }, + self.r, + self.g, + self.b + ) } } @@ -85,14 +102,14 @@ mod test { #[test] fn paint_yellow_foreground() { - let painted_fg = YELLOW.paint_fg(); + let painted_fg = YELLOW.make_styles(None); assert_eq!("33", painted_fg) } #[test] fn paint_magenta_background() { - let painted_bg = MAGENTA.paint_bg(); + let painted_bg = MAGENTA.make_styles(Some(PaintType::BG)); assert_eq!("45", painted_bg) } @@ -112,14 +129,14 @@ mod test { #[test] fn palette_paint_green_fg() { let green = PaletteColor { index: 118 }; - let painted_fg = green.paint_fg(); + let painted_fg = green.make_styles(None); assert_eq!("38;5;118", painted_fg) } #[test] fn palette_paint_blue_bg() { let blue = PaletteColor { index: 33 }; - let painted_bg = blue.paint_bg(); + let painted_bg = blue.make_styles(Some(PaintType::BG)); assert_eq!("48;5;33", painted_bg) } @@ -142,14 +159,14 @@ mod test { #[test] fn rgb_paint_purple_fg() { let purple = RGB { r: 126, g: 50, b: 219 }; - let painted_fg = purple.paint_fg(); + let painted_fg = purple.make_styles(None); assert_eq!("38;2;126;50;219", painted_fg) } #[test] fn rgb_paint_orange_bg() { let orange = RGB { r: 219, g: 132, b: 50 }; - let painted_bg = orange.paint_bg(); + let painted_bg = orange.make_styles(Some(PaintType::BG)); assert_eq!("48;2;219;132;50", painted_bg) } } From 17609c65f33eb97ebb0346e9df2fd5e503d1bb78 Mon Sep 17 00:00:00 2001 From: syaw0 Date: Sat, 2 Nov 2024 11:02:57 +0330 Subject: [PATCH 11/51] chore: rename package from Vitalux to vitalux for consistency --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 501903c..7404c03 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3,5 +3,5 @@ version = 3 [[package]] -name = "Vitalux" +name = "vitalux" version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml index 44387e4..2b66608 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "Vitalux" +name = "vitalux" version = "0.1.0" edition = "2021" description = "Colorize Your Terminal with Vitalux: A Rust-powered Formatting Tool" From 68b701e109bea543146e590af364160fc4871fef Mon Sep 17 00:00:00 2001 From: syaw0 Date: Sat, 2 Nov 2024 11:05:07 +0330 Subject: [PATCH 12/51] refactor: remove test.rs file and move tests to a module files --- src/ansi_escape_code.rs | 29 +++++++++++++++++++++++++++-- src/test.rs | 23 ----------------------- 2 files changed, 27 insertions(+), 25 deletions(-) delete mode 100644 src/test.rs diff --git a/src/ansi_escape_code.rs b/src/ansi_escape_code.rs index 7dbde5d..926003a 100644 --- a/src/ansi_escape_code.rs +++ b/src/ansi_escape_code.rs @@ -2,11 +2,36 @@ pub struct ANSIEscapeCode { parameter: String, } impl ANSIEscapeCode { - pub fn new(parameter: String) -> Self { - ANSIEscapeCode { parameter } + pub fn new(parameter: &str) -> Self { + ANSIEscapeCode { parameter: parameter.to_string() } } pub fn code(&self) -> String { format!("\\x1b[{}m", self.parameter) } } + +// ======================================================================= + +#[cfg(test)] +mod ansi_escape_code_test { + use super::*; + + #[test] + fn create_simple_ansi_code() { + let p = ANSIEscapeCode::new("33"); + assert_eq!(p.code(), "\\x1b[33m") + } + + #[test] + fn create_reset_ansi_code() { + let reset_ansi = ANSIEscapeCode::new("0"); + assert_eq!("\\x1b[0m", reset_ansi.code()); + } + + #[test] + fn create_bright_cyan_ansi_code() { + let reset_ansi = ANSIEscapeCode::new("96"); + assert_eq!("\\x1b[96m", reset_ansi.code()); + } +} diff --git a/src/test.rs b/src/test.rs deleted file mode 100644 index 2fc6eaa..0000000 --- a/src/test.rs +++ /dev/null @@ -1,23 +0,0 @@ -#[cfg(test)] -mod ansi_escape_code_test { - use crate::ansi_escape_code::ANSIEscapeCode; - use super::*; - - #[test] - fn create_simple_ansi_code() { - let p = ANSIEscapeCode::new(String::from("33")); - assert_eq!(p.code(), "\\x1b[33m") - } - - #[test] - fn create_reset_ansi_code() { - let reset_ansi = ANSIEscapeCode::new(String::from("0")); - assert_eq!("\\x1b[0m", reset_ansi.code()); - } - - #[test] - fn create_bright_cyan_ansi_code() { - let reset_ansi = ANSIEscapeCode::new(String::from("96")); - assert_eq!("\\x1b[96m", reset_ansi.code()); - } -} From c41e8d88829be86f9372567cb0d3fd187c3531c4 Mon Sep 17 00:00:00 2001 From: syaw0 Date: Sat, 2 Nov 2024 11:32:35 +0330 Subject: [PATCH 13/51] feat: Implement the Stylify for PaintType in this way we can add PaintType to list of start_styles --- src/colors.rs | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/colors.rs b/src/colors.rs index e853640..914ece1 100644 --- a/src/colors.rs +++ b/src/colors.rs @@ -1,10 +1,15 @@ +pub trait Stylify { + fn make_styles(&self, paint_type: Option) -> String; +} pub enum PaintType { FG, BG, } -pub trait Stylify { - fn make_styles(&self, paint_type: Option) -> String; +impl Stylify for PaintType { + fn make_styles(&self, _paint_type: Option) -> String { + String::new() + } } pub struct BasicColor { @@ -43,7 +48,7 @@ pub const BRIGHT_WHITE: BasicColor = BasicColor { fg: 97, bg: 107 }; // pub struct PaletteColor { - index: u8, + pub index: u8, } impl Stylify for PaletteColor { @@ -61,9 +66,9 @@ impl Stylify for PaletteColor { } pub struct RGB { - r: u8, - g: u8, - b: u8, + pub r: u8, + pub g: u8, + pub b: u8, } impl Stylify for RGB { From ffe74d40e2884878e11cfed9ef41aecb1317bd18 Mon Sep 17 00:00:00 2001 From: syaw0 Date: Sat, 2 Nov 2024 11:33:26 +0330 Subject: [PATCH 14/51] feat: Add StyledText struct and implement the public api for basic colors, palette and rgb --- src/styled_text.rs | 137 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 137 insertions(+) create mode 100644 src/styled_text.rs diff --git a/src/styled_text.rs b/src/styled_text.rs new file mode 100644 index 0000000..bcb1c49 --- /dev/null +++ b/src/styled_text.rs @@ -0,0 +1,137 @@ +use crate::colors::{ + PaintType, + PaletteColor, + Stylify, + RGB, + BLACK, + BLUE, + BRIGHT_BLUE, + BRIGHT_CYAN, + BRIGHT_GREEN, + BRIGHT_MAGENTA, + BRIGHT_RED, + BRIGHT_WHITE, + BRIGHT_YELLOW, + CYAN, + GRAY, + GREEN, + MAGENTA, + RED, + WHITE, + YELLOW, +}; + +// ======================================================================= + +// this is public api for users +/// # TXT +pub fn txt(text: &str) -> StyledText { + StyledText::new(text.to_string()) +} + +pub struct StyledText { + text: String, + start_styles: Vec>, + end_styles: Vec>, +} + +impl StyledText { + fn new(text: String) -> Self { + // we should use Formatter::reset() + // let reset_ansi = ANSIEscapeCode::new("0"); + StyledText { + text, + start_styles: vec![], + end_styles: vec![], + } + } + + pub fn paint(&mut self) -> String { + // Add formatter reset in the end + // self.end_styles.push(); + // format!() + String::new() + } + + pub fn fg(&mut self) { + self.start_styles.push(Box::new(PaintType::FG)); + } + + pub fn bg(&mut self) { + self.start_styles.push(Box::new(PaintType::BG)); + } + + // Colors + + pub fn rgb(&mut self, r: u8, g: u8, b: u8) { + self.start_styles.push(Box::new(RGB { r, g, b })); + } + + pub fn palette(&mut self, index: u8) { + self.start_styles.push(Box::new(PaletteColor { index })); + } + + pub fn black(&mut self) { + self.start_styles.push(Box::new(BLACK)); + } + + pub fn red(&mut self) { + self.start_styles.push(Box::new(RED)); + } + + pub fn green(&mut self) { + self.start_styles.push(Box::new(GREEN)); + } + + pub fn yellow(&mut self) { + self.start_styles.push(Box::new(YELLOW)); + } + + pub fn blue(&mut self) { + self.start_styles.push(Box::new(BLUE)); + } + + pub fn magenta(&mut self) { + self.start_styles.push(Box::new(MAGENTA)); + } + + pub fn cyan(&mut self) { + self.start_styles.push(Box::new(CYAN)); + } + + pub fn white(&mut self) { + self.start_styles.push(Box::new(WHITE)); + } + + pub fn gray(&mut self) { + self.start_styles.push(Box::new(GRAY)); + } + + pub fn bright_red(&mut self) { + self.start_styles.push(Box::new(BRIGHT_RED)); + } + + pub fn bright_green(&mut self) { + self.start_styles.push(Box::new(BRIGHT_GREEN)); + } + + pub fn bright_yellow(&mut self) { + self.start_styles.push(Box::new(BRIGHT_YELLOW)); + } + + pub fn bright_blue(&mut self) { + self.start_styles.push(Box::new(BRIGHT_BLUE)); + } + + pub fn bright_magenta(&mut self) { + self.start_styles.push(Box::new(BRIGHT_MAGENTA)); + } + + pub fn bright_cyan(&mut self) { + self.start_styles.push(Box::new(BRIGHT_CYAN)); + } + + pub fn bright_white(&mut self) { + self.start_styles.push(Box::new(BRIGHT_WHITE)); + } +} From ca0f229412d7c31cafd1b0e65d2e833c4f5a937d Mon Sep 17 00:00:00 2001 From: syaw0 Date: Sun, 3 Nov 2024 09:43:07 +0330 Subject: [PATCH 15/51] feat: Add Style enum and store style variants with their structs In this way we can easily get inside each variant and check the concrete type, that could not be done with traint objects and dyn trait --- src/colors.rs | 73 +++++++++++++++++++++++++++++++++------------------ 1 file changed, 47 insertions(+), 26 deletions(-) diff --git a/src/colors.rs b/src/colors.rs index 914ece1..4e9f7f3 100644 --- a/src/colors.rs +++ b/src/colors.rs @@ -1,11 +1,30 @@ pub trait Stylify { fn make_styles(&self, paint_type: Option) -> String; } + pub enum PaintType { FG, BG, } +pub enum Styles { + StyleRgb(Rgb), + StyleBasicColor(BasicColor), + StylePaletteColor(PaletteColor), + StylePaintType(PaintType), +} + +impl Styles { + fn make_styles(&self, paint_type: Option) -> String { + match self { + Styles::StyleBasicColor(c) => c.make_styles(paint_type), + Styles::StylePaintType(c) => c.make_styles(paint_type), + Styles::StylePaletteColor(c) => c.make_styles(paint_type), + Styles::StyleRgb(c) => c.make_styles(paint_type), + } + } +} + impl Stylify for PaintType { fn make_styles(&self, _paint_type: Option) -> String { String::new() @@ -28,22 +47,22 @@ impl Stylify for BasicColor { } } -pub const BLACK: BasicColor = BasicColor { fg: 30, bg: 40 }; -pub const RED: BasicColor = BasicColor { fg: 31, bg: 41 }; -pub const GREEN: BasicColor = BasicColor { fg: 32, bg: 42 }; -pub const YELLOW: BasicColor = BasicColor { fg: 33, bg: 43 }; -pub const BLUE: BasicColor = BasicColor { fg: 34, bg: 44 }; -pub const MAGENTA: BasicColor = BasicColor { fg: 35, bg: 45 }; -pub const CYAN: BasicColor = BasicColor { fg: 36, bg: 46 }; -pub const WHITE: BasicColor = BasicColor { fg: 37, bg: 47 }; -pub const GRAY: BasicColor = BasicColor { fg: 90, bg: 10 }; -pub const BRIGHT_RED: BasicColor = BasicColor { fg: 91, bg: 101 }; -pub const BRIGHT_GREEN: BasicColor = BasicColor { fg: 92, bg: 102 }; -pub const BRIGHT_YELLOW: BasicColor = BasicColor { fg: 93, bg: 103 }; -pub const BRIGHT_BLUE: BasicColor = BasicColor { fg: 94, bg: 104 }; -pub const BRIGHT_MAGENTA: BasicColor = BasicColor { fg: 95, bg: 105 }; -pub const BRIGHT_CYAN: BasicColor = BasicColor { fg: 96, bg: 106 }; -pub const BRIGHT_WHITE: BasicColor = BasicColor { fg: 97, bg: 107 }; +pub const BLACK: Styles = Styles::StyleBasicColor(BasicColor { fg: 30, bg: 40 }); +pub const RED: Styles = Styles::StyleBasicColor(BasicColor { fg: 31, bg: 41 }); +pub const GREEN: Styles = Styles::StyleBasicColor(BasicColor { fg: 32, bg: 42 }); +pub const YELLOW: Styles = Styles::StyleBasicColor(BasicColor { fg: 33, bg: 43 }); +pub const BLUE: Styles = Styles::StyleBasicColor(BasicColor { fg: 34, bg: 44 }); +pub const MAGENTA: Styles = Styles::StyleBasicColor(BasicColor { fg: 35, bg: 45 }); +pub const CYAN: Styles = Styles::StyleBasicColor(BasicColor { fg: 36, bg: 46 }); +pub const WHITE: Styles = Styles::StyleBasicColor(BasicColor { fg: 37, bg: 47 }); +pub const GRAY: Styles = Styles::StyleBasicColor(BasicColor { fg: 90, bg: 10 }); +pub const BRIGHT_RED: Styles = Styles::StyleBasicColor(BasicColor { fg: 91, bg: 101 }); +pub const BRIGHT_GREEN: Styles = Styles::StyleBasicColor(BasicColor { fg: 92, bg: 102 }); +pub const BRIGHT_YELLOW: Styles = Styles::StyleBasicColor(BasicColor { fg: 93, bg: 103 }); +pub const BRIGHT_BLUE: Styles = Styles::StyleBasicColor(BasicColor { fg: 94, bg: 104 }); +pub const BRIGHT_MAGENTA: Styles = Styles::StyleBasicColor(BasicColor { fg: 95, bg: 105 }); +pub const BRIGHT_CYAN: Styles = Styles::StyleBasicColor(BasicColor { fg: 96, bg: 106 }); +pub const BRIGHT_WHITE: Styles = Styles::StyleBasicColor(BasicColor { fg: 97, bg: 107 }); // @@ -65,13 +84,13 @@ impl Stylify for PaletteColor { } } -pub struct RGB { +pub struct Rgb { pub r: u8, pub g: u8, pub b: u8, } -impl Stylify for RGB { +impl Stylify for Rgb { fn make_styles(&self, paint_type: Option) -> String { let paint_type = paint_type.unwrap_or(PaintType::FG); format!( @@ -95,14 +114,16 @@ mod test { #[test] fn black_colors() { - assert_eq!(30, BLACK.fg); - assert_eq!(40, BLACK.bg) + let black = BasicColor { fg: 30, bg: 40 }; + assert_eq!(30, black.fg); + assert_eq!(40, black.bg) } #[test] fn cyan_colors() { - assert_eq!(36, CYAN.fg); - assert_eq!(46, CYAN.bg) + let cyan = BasicColor { fg: 36, bg: 46 }; + assert_eq!(36, cyan.fg); + assert_eq!(46, cyan.bg) } #[test] @@ -147,7 +168,7 @@ mod test { #[test] fn red_rgb_color() { - let red = RGB { r: 255, g: 0, b: 0 }; + let red = Rgb { r: 255, g: 0, b: 0 }; assert_eq!(255, red.r); assert_eq!(0, red.g); assert_eq!(0, red.b) @@ -155,7 +176,7 @@ mod test { #[test] fn salmon_rgb_color() { - let salmon = RGB { r: 250, g: 128, b: 114 }; + let salmon = Rgb { r: 250, g: 128, b: 114 }; assert_eq!(250, salmon.r); assert_eq!(128, salmon.g); assert_eq!(114, salmon.b) @@ -163,14 +184,14 @@ mod test { #[test] fn rgb_paint_purple_fg() { - let purple = RGB { r: 126, g: 50, b: 219 }; + let purple = Rgb { r: 126, g: 50, b: 219 }; let painted_fg = purple.make_styles(None); assert_eq!("38;2;126;50;219", painted_fg) } #[test] fn rgb_paint_orange_bg() { - let orange = RGB { r: 219, g: 132, b: 50 }; + let orange = Rgb { r: 219, g: 132, b: 50 }; let painted_bg = orange.make_styles(Some(PaintType::BG)); assert_eq!("48;2;219;132;50", painted_bg) } From be0cbeaded5c64250ce688a5243c7c153e3700af Mon Sep 17 00:00:00 2001 From: syaw0 Date: Sun, 3 Nov 2024 09:45:02 +0330 Subject: [PATCH 16/51] feat: Use new implementation for styled_text --- src/styled_text.rs | 128 ++++++++++++++++++++++++++++++--------------- 1 file changed, 86 insertions(+), 42 deletions(-) diff --git a/src/styled_text.rs b/src/styled_text.rs index bcb1c49..e50468d 100644 --- a/src/styled_text.rs +++ b/src/styled_text.rs @@ -1,8 +1,8 @@ use crate::colors::{ PaintType, PaletteColor, + Styles, Stylify, - RGB, BLACK, BLUE, BRIGHT_BLUE, @@ -17,6 +17,7 @@ use crate::colors::{ GREEN, MAGENTA, RED, + Rgb, WHITE, YELLOW, }; @@ -31,7 +32,7 @@ pub fn txt(text: &str) -> StyledText { pub struct StyledText { text: String, - start_styles: Vec>, + start_styles: Vec, end_styles: Vec>, } @@ -47,91 +48,134 @@ impl StyledText { } pub fn paint(&mut self) -> String { + let indexes: Vec = self.start_styles + .iter() + .enumerate() + .filter_map(|(index, style)| { + match style { + Styles::StylePaintType(_) => Some(index), + _ => None, + } + }) + .collect(); + + println!("{:?}", indexes); // Add formatter reset in the end // self.end_styles.push(); // format!() String::new() } - pub fn fg(&mut self) { - self.start_styles.push(Box::new(PaintType::FG)); + pub fn fg(&mut self) -> &mut Self { + self.start_styles.push(Styles::StylePaintType(PaintType::FG)); + self } - pub fn bg(&mut self) { - self.start_styles.push(Box::new(PaintType::BG)); + pub fn bg(&mut self) -> &mut Self { + self.start_styles.push(Styles::StylePaintType(PaintType::BG)); + self } // Colors - pub fn rgb(&mut self, r: u8, g: u8, b: u8) { - self.start_styles.push(Box::new(RGB { r, g, b })); + pub fn rgb(&mut self, r: u8, g: u8, b: u8) -> &mut Self { + self.start_styles.push(Styles::StyleRgb(Rgb { r, g, b })); + self } - pub fn palette(&mut self, index: u8) { - self.start_styles.push(Box::new(PaletteColor { index })); + pub fn palette(&mut self, index: u8) -> &mut Self { + self.start_styles.push(Styles::StylePaletteColor(PaletteColor { index })); + self } - pub fn black(&mut self) { - self.start_styles.push(Box::new(BLACK)); + pub fn black(&mut self) -> &mut Self { + self.start_styles.push(BLACK); + self } - pub fn red(&mut self) { - self.start_styles.push(Box::new(RED)); + pub fn red(&mut self) -> &mut Self { + self.start_styles.push(RED); + self } - pub fn green(&mut self) { - self.start_styles.push(Box::new(GREEN)); + pub fn green(&mut self) -> &mut Self { + self.start_styles.push(GREEN); + self } - pub fn yellow(&mut self) { - self.start_styles.push(Box::new(YELLOW)); + pub fn yellow(&mut self) -> &mut Self { + self.start_styles.push(YELLOW); + self } - pub fn blue(&mut self) { - self.start_styles.push(Box::new(BLUE)); + pub fn blue(&mut self) -> &mut Self { + self.start_styles.push(BLUE); + self } - pub fn magenta(&mut self) { - self.start_styles.push(Box::new(MAGENTA)); + pub fn magenta(&mut self) -> &mut Self { + self.start_styles.push(MAGENTA); + self } - pub fn cyan(&mut self) { - self.start_styles.push(Box::new(CYAN)); + pub fn cyan(&mut self) -> &mut Self { + self.start_styles.push(CYAN); + self } - pub fn white(&mut self) { - self.start_styles.push(Box::new(WHITE)); + pub fn white(&mut self) -> &mut Self { + self.start_styles.push(WHITE); + self } - pub fn gray(&mut self) { - self.start_styles.push(Box::new(GRAY)); + pub fn gray(&mut self) -> &mut Self { + self.start_styles.push(GRAY); + self } - pub fn bright_red(&mut self) { - self.start_styles.push(Box::new(BRIGHT_RED)); + pub fn bright_red(&mut self) -> &mut Self { + self.start_styles.push(BRIGHT_RED); + self } - pub fn bright_green(&mut self) { - self.start_styles.push(Box::new(BRIGHT_GREEN)); + pub fn bright_green(&mut self) -> &mut Self { + self.start_styles.push(BRIGHT_GREEN); + self } - pub fn bright_yellow(&mut self) { - self.start_styles.push(Box::new(BRIGHT_YELLOW)); + pub fn bright_yellow(&mut self) -> &mut Self { + self.start_styles.push(BRIGHT_YELLOW); + self } - pub fn bright_blue(&mut self) { - self.start_styles.push(Box::new(BRIGHT_BLUE)); + pub fn bright_blue(&mut self) -> &mut Self { + self.start_styles.push(BRIGHT_BLUE); + self } - pub fn bright_magenta(&mut self) { - self.start_styles.push(Box::new(BRIGHT_MAGENTA)); + pub fn bright_magenta(&mut self) -> &mut Self { + self.start_styles.push(BRIGHT_MAGENTA); + self } - pub fn bright_cyan(&mut self) { - self.start_styles.push(Box::new(BRIGHT_CYAN)); + pub fn bright_cyan(&mut self) -> &mut Self { + self.start_styles.push(BRIGHT_CYAN); + self } - pub fn bright_white(&mut self) { - self.start_styles.push(Box::new(BRIGHT_WHITE)); + pub fn bright_white(&mut self) -> &mut Self { + self.start_styles.push(BRIGHT_WHITE); + self + } +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn test_paint_type() { + let txt = txt("Siavash").bright_blue().fg().red().yellow().bg().paint(); + assert_eq!(true, false); } } From 169ac5965ca5e7d03237524fa5ad995c8a625c18 Mon Sep 17 00:00:00 2001 From: syaw0 Date: Sun, 3 Nov 2024 10:15:13 +0330 Subject: [PATCH 17/51] feat: Add Clone to Styles variant structs --- src/colors.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/colors.rs b/src/colors.rs index 4e9f7f3..c7c0f08 100644 --- a/src/colors.rs +++ b/src/colors.rs @@ -1,12 +1,13 @@ pub trait Stylify { fn make_styles(&self, paint_type: Option) -> String; } - +#[derive(Debug, Clone)] pub enum PaintType { FG, BG, } +#[derive(Debug, Clone)] pub enum Styles { StyleRgb(Rgb), StyleBasicColor(BasicColor), @@ -30,7 +31,7 @@ impl Stylify for PaintType { String::new() } } - +#[derive(Debug, Clone)] pub struct BasicColor { fg: u8, bg: u8, @@ -65,7 +66,7 @@ pub const BRIGHT_CYAN: Styles = Styles::StyleBasicColor(BasicColor { fg: 96, bg: pub const BRIGHT_WHITE: Styles = Styles::StyleBasicColor(BasicColor { fg: 97, bg: 107 }); // - +#[derive(Debug, Clone)] pub struct PaletteColor { pub index: u8, } @@ -83,7 +84,7 @@ impl Stylify for PaletteColor { ) } } - +#[derive(Debug, Clone)] pub struct Rgb { pub r: u8, pub g: u8, From 363697b4f352f0392b5f255cff25b67d395d4688 Mon Sep 17 00:00:00 2001 From: syaw0 Date: Sun, 3 Nov 2024 10:15:38 +0330 Subject: [PATCH 18/51] feat : Use default paint type if there is only one or zero pain type in the start_styles --- src/styled_text.rs | 54 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) diff --git a/src/styled_text.rs b/src/styled_text.rs index e50468d..d097e30 100644 --- a/src/styled_text.rs +++ b/src/styled_text.rs @@ -48,6 +48,8 @@ impl StyledText { } pub fn paint(&mut self) -> String { + println!("{:?}", self.start_styles); + let mut default_paint_type = Styles::StylePaintType(PaintType::FG); let indexes: Vec = self.start_styles .iter() .enumerate() @@ -59,6 +61,19 @@ impl StyledText { }) .collect(); + if indexes.len() == 1 { + // We sure about 1 element exist on i + default_paint_type = self.start_styles + .get(indexes[0]) + .unwrap_or(&default_paint_type) + .clone(); + + // * call for make style on start_styles + } + if indexes.len() > 1 { + // * each slice get it's own paint type! + } + println!("{:?}", indexes); // Add formatter reset in the end // self.end_styles.push(); @@ -175,7 +190,44 @@ mod test { #[test] fn test_paint_type() { - let txt = txt("Siavash").bright_blue().fg().red().yellow().bg().paint(); + let txt = txt("Siavash").bright_blue().fg().red().bg().paint(); assert_eq!(true, false); } + + #[test] + fn test_with_one_paint_type() { + let no: Vec = txt("Hello there") + .bright_blue() + .red() + .bg() + .start_styles.iter() + .filter(|s| { + match s { + Styles::StylePaintType(_) => true, + _ => false, + } + }) + .cloned() + .collect(); + + assert_eq!(no.len(), 1) + } + + #[test] + fn test_with_zero_paint_type() { + let no: Vec = txt("Hello there") + .bright_blue() + .red() + .start_styles.iter() + .filter(|s| { + match s { + Styles::StylePaintType(_) => true, + _ => false, + } + }) + .cloned() + .collect(); + + assert_eq!(no.len(), 0) + } } From c5f297fb3df1d19940e088a0e20b0b46f3ad0d1d Mon Sep 17 00:00:00 2001 From: syaw0 Date: Sun, 3 Nov 2024 11:21:10 +0330 Subject: [PATCH 19/51] fix: Remove the extra \ from ANSIEscapeCode --- src/ansi_escape_code.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/ansi_escape_code.rs b/src/ansi_escape_code.rs index 926003a..110b29c 100644 --- a/src/ansi_escape_code.rs +++ b/src/ansi_escape_code.rs @@ -7,7 +7,7 @@ impl ANSIEscapeCode { } pub fn code(&self) -> String { - format!("\\x1b[{}m", self.parameter) + format!("\x1b[{}m", self.parameter) } } @@ -20,18 +20,18 @@ mod ansi_escape_code_test { #[test] fn create_simple_ansi_code() { let p = ANSIEscapeCode::new("33"); - assert_eq!(p.code(), "\\x1b[33m") + assert_eq!(p.code(), "\x1b[33m") } #[test] fn create_reset_ansi_code() { let reset_ansi = ANSIEscapeCode::new("0"); - assert_eq!("\\x1b[0m", reset_ansi.code()); + assert_eq!("\x1b[0m", reset_ansi.code()); } #[test] fn create_bright_cyan_ansi_code() { let reset_ansi = ANSIEscapeCode::new("96"); - assert_eq!("\\x1b[96m", reset_ansi.code()); + assert_eq!("\x1b[96m", reset_ansi.code()); } } From bdd27b4e2e5d995ef6ff48300ad8125e36fa30af Mon Sep 17 00:00:00 2001 From: syaw0 Date: Sun, 3 Nov 2024 11:22:03 +0330 Subject: [PATCH 20/51] feat: Develop the paint method that merge all styles into String --- src/styled_text.rs | 88 +++++++++++++++++++++------------------------- 1 file changed, 41 insertions(+), 47 deletions(-) diff --git a/src/styled_text.rs b/src/styled_text.rs index d097e30..ca095f4 100644 --- a/src/styled_text.rs +++ b/src/styled_text.rs @@ -1,25 +1,28 @@ -use crate::colors::{ - PaintType, - PaletteColor, - Styles, - Stylify, - BLACK, - BLUE, - BRIGHT_BLUE, - BRIGHT_CYAN, - BRIGHT_GREEN, - BRIGHT_MAGENTA, - BRIGHT_RED, - BRIGHT_WHITE, - BRIGHT_YELLOW, - CYAN, - GRAY, - GREEN, - MAGENTA, - RED, - Rgb, - WHITE, - YELLOW, +use crate::{ + ansi_escape_code::ANSIEscapeCode, + colors::{ + PaintType, + PaletteColor, + Rgb, + Styles, + Stylify, + BLACK, + BLUE, + BRIGHT_BLUE, + BRIGHT_CYAN, + BRIGHT_GREEN, + BRIGHT_MAGENTA, + BRIGHT_RED, + BRIGHT_WHITE, + BRIGHT_YELLOW, + CYAN, + GRAY, + GREEN, + MAGENTA, + RED, + WHITE, + YELLOW, + }, }; // ======================================================================= @@ -49,36 +52,27 @@ impl StyledText { pub fn paint(&mut self) -> String { println!("{:?}", self.start_styles); - let mut default_paint_type = Styles::StylePaintType(PaintType::FG); - let indexes: Vec = self.start_styles + let mut default_paint_type = PaintType::FG; + + let start_codes_list: Vec = self.start_styles .iter() - .enumerate() - .filter_map(|(index, style)| { - match style { - Styles::StylePaintType(_) => Some(index), - _ => None, + .rev() + .filter_map(|s| { + if let Styles::StylePaintType(p) = s { + default_paint_type = p.clone(); + return None; } + let t = s.make_styles(Some(&default_paint_type)); + Some(ANSIEscapeCode::new(t.as_str()).code()) }) + .collect::>() + .into_iter() + .rev() .collect(); + let start_codes = start_codes_list.join(""); + let end_codes = ANSIEscapeCode::new("0").code(); - if indexes.len() == 1 { - // We sure about 1 element exist on i - default_paint_type = self.start_styles - .get(indexes[0]) - .unwrap_or(&default_paint_type) - .clone(); - - // * call for make style on start_styles - } - if indexes.len() > 1 { - // * each slice get it's own paint type! - } - - println!("{:?}", indexes); - // Add formatter reset in the end - // self.end_styles.push(); - // format!() - String::new() + format!("{}{}{}", start_codes, self.text, end_codes) } pub fn fg(&mut self) -> &mut Self { From d0c6ff5dc33fbcc150b2ddd4dd628794bd08fdd5 Mon Sep 17 00:00:00 2001 From: syaw0 Date: Sun, 3 Nov 2024 11:29:55 +0330 Subject: [PATCH 21/51] feat: Using ref PaintType in make_styles trait method --- src/colors.rs | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/colors.rs b/src/colors.rs index c7c0f08..7b1a6e3 100644 --- a/src/colors.rs +++ b/src/colors.rs @@ -1,5 +1,5 @@ pub trait Stylify { - fn make_styles(&self, paint_type: Option) -> String; + fn make_styles(&self, paint_type: Option<&PaintType>) -> String; } #[derive(Debug, Clone)] pub enum PaintType { @@ -16,7 +16,7 @@ pub enum Styles { } impl Styles { - fn make_styles(&self, paint_type: Option) -> String { + pub fn make_styles(&self, paint_type: Option<&PaintType>) -> String { match self { Styles::StyleBasicColor(c) => c.make_styles(paint_type), Styles::StylePaintType(c) => c.make_styles(paint_type), @@ -27,7 +27,7 @@ impl Styles { } impl Stylify for PaintType { - fn make_styles(&self, _paint_type: Option) -> String { + fn make_styles(&self, _paint_type: Option<&PaintType>) -> String { String::new() } } @@ -39,8 +39,8 @@ pub struct BasicColor { impl Stylify for BasicColor { /// If the `is_foreground` was None it's assume as foreground - fn make_styles(&self, paint_type: Option) -> String { - let paint_type = paint_type.unwrap_or(PaintType::FG); + fn make_styles(&self, paint_type: Option<&PaintType>) -> String { + let paint_type = paint_type.unwrap_or(&PaintType::FG); format!("{}", match paint_type { PaintType::FG => self.fg, PaintType::BG => self.bg, @@ -72,8 +72,8 @@ pub struct PaletteColor { } impl Stylify for PaletteColor { - fn make_styles(&self, paint_type: Option) -> String { - let paint_type = paint_type.unwrap_or(PaintType::FG); + fn make_styles(&self, paint_type: Option<&PaintType>) -> String { + let paint_type = paint_type.unwrap_or(&PaintType::FG); format!( "{};5;{}", match paint_type { @@ -92,8 +92,8 @@ pub struct Rgb { } impl Stylify for Rgb { - fn make_styles(&self, paint_type: Option) -> String { - let paint_type = paint_type.unwrap_or(PaintType::FG); + fn make_styles(&self, paint_type: Option<&PaintType>) -> String { + let paint_type = paint_type.unwrap_or(&PaintType::FG); format!( "{};2;{};{};{}", match paint_type { @@ -136,7 +136,7 @@ mod test { #[test] fn paint_magenta_background() { - let painted_bg = MAGENTA.make_styles(Some(PaintType::BG)); + let painted_bg = MAGENTA.make_styles(Some(&PaintType::BG)); assert_eq!("45", painted_bg) } @@ -163,7 +163,7 @@ mod test { #[test] fn palette_paint_blue_bg() { let blue = PaletteColor { index: 33 }; - let painted_bg = blue.make_styles(Some(PaintType::BG)); + let painted_bg = blue.make_styles(Some(&PaintType::BG)); assert_eq!("48;5;33", painted_bg) } @@ -193,7 +193,7 @@ mod test { #[test] fn rgb_paint_orange_bg() { let orange = Rgb { r: 219, g: 132, b: 50 }; - let painted_bg = orange.make_styles(Some(PaintType::BG)); + let painted_bg = orange.make_styles(Some(&PaintType::BG)); assert_eq!("48;2;219;132;50", painted_bg) } } From a322ef404787f8193806e133cd447d062c670300 Mon Sep 17 00:00:00 2001 From: syaw0 Date: Sun, 3 Nov 2024 11:31:33 +0330 Subject: [PATCH 22/51] test: Add test for basic color styles --- src/styled_text.rs | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/styled_text.rs b/src/styled_text.rs index ca095f4..e9c2111 100644 --- a/src/styled_text.rs +++ b/src/styled_text.rs @@ -51,7 +51,6 @@ impl StyledText { } pub fn paint(&mut self) -> String { - println!("{:?}", self.start_styles); let mut default_paint_type = PaintType::FG; let start_codes_list: Vec = self.start_styles @@ -183,9 +182,16 @@ mod test { use super::*; #[test] - fn test_paint_type() { - let txt = txt("Siavash").bright_blue().fg().red().bg().paint(); - assert_eq!(true, false); + fn white_fg_black_bg() { + let raw_text = "I'm So Happy"; + let styled_text = txt(raw_text).white().bg().black().fg().paint(); + assert_eq!(styled_text, "\x1b[47m\x1b[30mI'm So Happy\x1b[0m"); + } + + fn blue_fg_bright_cyan_bg() { + let raw_text = "Silence is power"; + let styled_text = txt(raw_text).blue().fg().bright_cyan().bg().paint(); + assert_eq!(styled_text, "\x1b[34m\x1b[106mSilence is power\x1b[0m"); } #[test] From 4d0647dd8aa18dd1434448f4dd346c86d03b0a46 Mon Sep 17 00:00:00 2001 From: syaw0 Date: Mon, 4 Nov 2024 09:45:45 +0330 Subject: [PATCH 23/51] feat: Add Formatter struct --- src/colors.rs | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/colors.rs b/src/colors.rs index 7b1a6e3..674f404 100644 --- a/src/colors.rs +++ b/src/colors.rs @@ -7,12 +7,33 @@ pub enum PaintType { BG, } +#[derive(Debug, Clone)] +struct Formatter { + n: u8, +} + +impl Stylify for Formatter { + fn make_styles(&self, _paint_type: Option<&PaintType>) -> String { + format!("{}", self.n) + } +} + +pub const RESET: Styles = Styles::StyleFormatter(Formatter { n: 0 }); +pub const BOLD: Styles = Styles::StyleFormatter(Formatter { n: 1 }); +pub const FAINT: Styles = Styles::StyleFormatter(Formatter { n: 2 }); +pub const ITALIC: Styles = Styles::StyleFormatter(Formatter { n: 3 }); +pub const UNDERLINE: Styles = Styles::StyleFormatter(Formatter { n: 4 }); +pub const SLOW_BLINK: Styles = Styles::StyleFormatter(Formatter { n: 5 }); +pub const RAPID_BLINK: Styles = Styles::StyleFormatter(Formatter { n: 6 }); +pub const OVERLINE: Styles = Styles::StyleFormatter(Formatter { n: 53 }); + #[derive(Debug, Clone)] pub enum Styles { StyleRgb(Rgb), StyleBasicColor(BasicColor), StylePaletteColor(PaletteColor), StylePaintType(PaintType), + StyleFormatter(Formatter), } impl Styles { @@ -22,6 +43,7 @@ impl Styles { Styles::StylePaintType(c) => c.make_styles(paint_type), Styles::StylePaletteColor(c) => c.make_styles(paint_type), Styles::StyleRgb(c) => c.make_styles(paint_type), + Styles::StyleFormatter(c) => c.make_styles(paint_type), } } } From 427a129c242d8b20c971bc0a7787b1ee61e91a03 Mon Sep 17 00:00:00 2001 From: syaw0 Date: Mon, 4 Nov 2024 09:46:39 +0330 Subject: [PATCH 24/51] feat: Add methods to format text --- src/styled_text.rs | 47 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/src/styled_text.rs b/src/styled_text.rs index e9c2111..215d19a 100644 --- a/src/styled_text.rs +++ b/src/styled_text.rs @@ -8,6 +8,7 @@ use crate::{ Stylify, BLACK, BLUE, + BOLD, BRIGHT_BLUE, BRIGHT_CYAN, BRIGHT_GREEN, @@ -16,10 +17,17 @@ use crate::{ BRIGHT_WHITE, BRIGHT_YELLOW, CYAN, + FAINT, GRAY, GREEN, + ITALIC, MAGENTA, + OVERLINE, + RAPID_BLINK, RED, + RESET, + SLOW_BLINK, + UNDERLINE, WHITE, YELLOW, }, @@ -69,7 +77,7 @@ impl StyledText { .rev() .collect(); let start_codes = start_codes_list.join(""); - let end_codes = ANSIEscapeCode::new("0").code(); + let end_codes = ANSIEscapeCode::new(&RESET.make_styles(Some(&default_paint_type))).code(); format!("{}{}{}", start_codes, self.text, end_codes) } @@ -175,6 +183,43 @@ impl StyledText { self.start_styles.push(BRIGHT_WHITE); self } + + // formatters + + pub fn bold(&mut self) -> &mut Self { + self.start_styles.push(BOLD); + self + } + + pub fn faint(&mut self) -> &mut Self { + self.start_styles.push(FAINT); + self + } + + pub fn italic(&mut self) -> &mut Self { + self.start_styles.push(ITALIC); + self + } + + pub fn underline(&mut self) -> &mut Self { + self.start_styles.push(UNDERLINE); + self + } + + pub fn slow_blink(&mut self) -> &mut Self { + self.start_styles.push(SLOW_BLINK); + self + } + + pub fn rapid_blink(&mut self) -> &mut Self { + self.start_styles.push(RAPID_BLINK); + self + } + + pub fn overline(&mut self) -> &mut Self { + self.start_styles.push(OVERLINE); + self + } } #[cfg(test)] From ad2546d87696f72225cd7c6196a42533b0ee6f8d Mon Sep 17 00:00:00 2001 From: syaw0 Date: Mon, 4 Nov 2024 10:02:21 +0330 Subject: [PATCH 25/51] feat: Add reset method and change txt public api to styled --- src/styled_text.rs | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/styled_text.rs b/src/styled_text.rs index 215d19a..2234ceb 100644 --- a/src/styled_text.rs +++ b/src/styled_text.rs @@ -37,7 +37,7 @@ use crate::{ // this is public api for users /// # TXT -pub fn txt(text: &str) -> StyledText { +pub fn styled(text: &str) -> StyledText { StyledText::new(text.to_string()) } @@ -186,6 +186,11 @@ impl StyledText { // formatters + pub fn reset(&mut self) -> &mut Self { + self.start_styles.push(RESET); + self + } + pub fn bold(&mut self) -> &mut Self { self.start_styles.push(BOLD); self @@ -229,19 +234,19 @@ mod test { #[test] fn white_fg_black_bg() { let raw_text = "I'm So Happy"; - let styled_text = txt(raw_text).white().bg().black().fg().paint(); + let styled_text = styled(raw_text).white().bg().black().fg().paint(); assert_eq!(styled_text, "\x1b[47m\x1b[30mI'm So Happy\x1b[0m"); } fn blue_fg_bright_cyan_bg() { let raw_text = "Silence is power"; - let styled_text = txt(raw_text).blue().fg().bright_cyan().bg().paint(); + let styled_text = styled(raw_text).blue().fg().bright_cyan().bg().paint(); assert_eq!(styled_text, "\x1b[34m\x1b[106mSilence is power\x1b[0m"); } #[test] fn test_with_one_paint_type() { - let no: Vec = txt("Hello there") + let no: Vec = styled("Hello there") .bright_blue() .red() .bg() @@ -260,7 +265,7 @@ mod test { #[test] fn test_with_zero_paint_type() { - let no: Vec = txt("Hello there") + let no: Vec = styled("Hello there") .bright_blue() .red() .start_styles.iter() From 874e156b9658de8378468ba8a814fe1041bac47a Mon Sep 17 00:00:00 2001 From: syaw0 Date: Mon, 4 Nov 2024 10:06:06 +0330 Subject: [PATCH 26/51] doc: Add basic documantation for styled method --- src/styled_text.rs | 48 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 46 insertions(+), 2 deletions(-) diff --git a/src/styled_text.rs b/src/styled_text.rs index 2234ceb..f9e9b31 100644 --- a/src/styled_text.rs +++ b/src/styled_text.rs @@ -35,8 +35,52 @@ use crate::{ // ======================================================================= -// this is public api for users -/// # TXT +/// Creates a styled text string with the given text and styles. +/// +/// This function returns a `StyledText` object that can be customized with various styles, +/// colors, and effects. The resulting styled text can be printed or used in other contexts. +/// +/// # Examples +/// +/// ``` +/// use vitalux::styled; +/// +/// let txt = styled("Happy Day!") +/// .rgb(204, 182, 122) +/// .italic() +/// .rapid_blink() +/// .bg() +/// .rgb(74, 56, 7) +/// .fg() +/// .paint(); +/// println!("{txt}"); +/// ``` +/// +/// # Styles +/// +/// The following styles can be applied to the text: +/// +/// * `rgb(r, g, b)`: Sets the text color to the given RGB values. +/// * `italic()`: Sets the text to italic. +/// * `rapid_blink()`: Sets the text to rapidly blink. +/// * `bg()`: Sets the background color. +/// * `fg()`: Sets the foreground color. +/// +/// # Colors +/// +/// The following colors can be used with the `rgb` method: +/// +/// * `rgb(r, g, b)`: Sets the color to the given RGB values. +/// +/// # Effects +/// +/// The following effects can be applied to the text: +/// +/// * `rapid_blink()`: Sets the text to rapidly blink. +/// +/// # Returns +/// +/// A `StyledText` object that can be printed or used in other contexts. pub fn styled(text: &str) -> StyledText { StyledText::new(text.to_string()) } From fb1a1c020d0105a9be5784b36652a6a26759935c Mon Sep 17 00:00:00 2001 From: syaw0 Date: Mon, 4 Nov 2024 10:08:49 +0330 Subject: [PATCH 27/51] refactor: extract the Stylify trait to traits.rs module and update the rest of the code --- src/colors.rs | 7 +++---- src/styled_text.rs | 4 +--- src/traits.rs | 5 +++++ 3 files changed, 9 insertions(+), 7 deletions(-) create mode 100644 src/traits.rs diff --git a/src/colors.rs b/src/colors.rs index 674f404..ca79516 100644 --- a/src/colors.rs +++ b/src/colors.rs @@ -1,6 +1,5 @@ -pub trait Stylify { - fn make_styles(&self, paint_type: Option<&PaintType>) -> String; -} +use crate::traits::Stylify; + #[derive(Debug, Clone)] pub enum PaintType { FG, @@ -8,7 +7,7 @@ pub enum PaintType { } #[derive(Debug, Clone)] -struct Formatter { +pub struct Formatter { n: u8, } diff --git a/src/styled_text.rs b/src/styled_text.rs index f9e9b31..9da75f6 100644 --- a/src/styled_text.rs +++ b/src/styled_text.rs @@ -5,7 +5,6 @@ use crate::{ PaletteColor, Rgb, Styles, - Stylify, BLACK, BLUE, BOLD, @@ -88,7 +87,6 @@ pub fn styled(text: &str) -> StyledText { pub struct StyledText { text: String, start_styles: Vec, - end_styles: Vec>, } impl StyledText { @@ -98,7 +96,6 @@ impl StyledText { StyledText { text, start_styles: vec![], - end_styles: vec![], } } @@ -282,6 +279,7 @@ mod test { assert_eq!(styled_text, "\x1b[47m\x1b[30mI'm So Happy\x1b[0m"); } + #[test] fn blue_fg_bright_cyan_bg() { let raw_text = "Silence is power"; let styled_text = styled(raw_text).blue().fg().bright_cyan().bg().paint(); diff --git a/src/traits.rs b/src/traits.rs new file mode 100644 index 0000000..2302d2e --- /dev/null +++ b/src/traits.rs @@ -0,0 +1,5 @@ +use crate::colors::PaintType; + +pub trait Stylify { + fn make_styles(&self, paint_type: Option<&PaintType>) -> String; +} From a56c44118ae16398bf94fc2eb3d3092e67c9e0df Mon Sep 17 00:00:00 2001 From: syaw0 Date: Tue, 5 Nov 2024 10:10:20 +0330 Subject: [PATCH 28/51] refactor(colors.rs): just break the file into multiple module --- src/colors.rs | 220 -------------------------------------- src/lib.rs | 6 +- src/styled_text.rs | 86 ++++++--------- src/styles.rs | 40 +++++++ src/styles/basic_color.rs | 37 +++++++ src/styles/formatter.rs | 23 ++++ src/styles/paint_type.rs | 15 +++ src/styles/palette.rs | 22 ++++ src/styles/rgb.rs | 26 +++++ src/traits.rs | 5 - 10 files changed, 201 insertions(+), 279 deletions(-) delete mode 100644 src/colors.rs create mode 100644 src/styles.rs create mode 100644 src/styles/basic_color.rs create mode 100644 src/styles/formatter.rs create mode 100644 src/styles/paint_type.rs create mode 100644 src/styles/palette.rs create mode 100644 src/styles/rgb.rs delete mode 100644 src/traits.rs diff --git a/src/colors.rs b/src/colors.rs deleted file mode 100644 index ca79516..0000000 --- a/src/colors.rs +++ /dev/null @@ -1,220 +0,0 @@ -use crate::traits::Stylify; - -#[derive(Debug, Clone)] -pub enum PaintType { - FG, - BG, -} - -#[derive(Debug, Clone)] -pub struct Formatter { - n: u8, -} - -impl Stylify for Formatter { - fn make_styles(&self, _paint_type: Option<&PaintType>) -> String { - format!("{}", self.n) - } -} - -pub const RESET: Styles = Styles::StyleFormatter(Formatter { n: 0 }); -pub const BOLD: Styles = Styles::StyleFormatter(Formatter { n: 1 }); -pub const FAINT: Styles = Styles::StyleFormatter(Formatter { n: 2 }); -pub const ITALIC: Styles = Styles::StyleFormatter(Formatter { n: 3 }); -pub const UNDERLINE: Styles = Styles::StyleFormatter(Formatter { n: 4 }); -pub const SLOW_BLINK: Styles = Styles::StyleFormatter(Formatter { n: 5 }); -pub const RAPID_BLINK: Styles = Styles::StyleFormatter(Formatter { n: 6 }); -pub const OVERLINE: Styles = Styles::StyleFormatter(Formatter { n: 53 }); - -#[derive(Debug, Clone)] -pub enum Styles { - StyleRgb(Rgb), - StyleBasicColor(BasicColor), - StylePaletteColor(PaletteColor), - StylePaintType(PaintType), - StyleFormatter(Formatter), -} - -impl Styles { - pub fn make_styles(&self, paint_type: Option<&PaintType>) -> String { - match self { - Styles::StyleBasicColor(c) => c.make_styles(paint_type), - Styles::StylePaintType(c) => c.make_styles(paint_type), - Styles::StylePaletteColor(c) => c.make_styles(paint_type), - Styles::StyleRgb(c) => c.make_styles(paint_type), - Styles::StyleFormatter(c) => c.make_styles(paint_type), - } - } -} - -impl Stylify for PaintType { - fn make_styles(&self, _paint_type: Option<&PaintType>) -> String { - String::new() - } -} -#[derive(Debug, Clone)] -pub struct BasicColor { - fg: u8, - bg: u8, -} - -impl Stylify for BasicColor { - /// If the `is_foreground` was None it's assume as foreground - fn make_styles(&self, paint_type: Option<&PaintType>) -> String { - let paint_type = paint_type.unwrap_or(&PaintType::FG); - format!("{}", match paint_type { - PaintType::FG => self.fg, - PaintType::BG => self.bg, - }) - } -} - -pub const BLACK: Styles = Styles::StyleBasicColor(BasicColor { fg: 30, bg: 40 }); -pub const RED: Styles = Styles::StyleBasicColor(BasicColor { fg: 31, bg: 41 }); -pub const GREEN: Styles = Styles::StyleBasicColor(BasicColor { fg: 32, bg: 42 }); -pub const YELLOW: Styles = Styles::StyleBasicColor(BasicColor { fg: 33, bg: 43 }); -pub const BLUE: Styles = Styles::StyleBasicColor(BasicColor { fg: 34, bg: 44 }); -pub const MAGENTA: Styles = Styles::StyleBasicColor(BasicColor { fg: 35, bg: 45 }); -pub const CYAN: Styles = Styles::StyleBasicColor(BasicColor { fg: 36, bg: 46 }); -pub const WHITE: Styles = Styles::StyleBasicColor(BasicColor { fg: 37, bg: 47 }); -pub const GRAY: Styles = Styles::StyleBasicColor(BasicColor { fg: 90, bg: 10 }); -pub const BRIGHT_RED: Styles = Styles::StyleBasicColor(BasicColor { fg: 91, bg: 101 }); -pub const BRIGHT_GREEN: Styles = Styles::StyleBasicColor(BasicColor { fg: 92, bg: 102 }); -pub const BRIGHT_YELLOW: Styles = Styles::StyleBasicColor(BasicColor { fg: 93, bg: 103 }); -pub const BRIGHT_BLUE: Styles = Styles::StyleBasicColor(BasicColor { fg: 94, bg: 104 }); -pub const BRIGHT_MAGENTA: Styles = Styles::StyleBasicColor(BasicColor { fg: 95, bg: 105 }); -pub const BRIGHT_CYAN: Styles = Styles::StyleBasicColor(BasicColor { fg: 96, bg: 106 }); -pub const BRIGHT_WHITE: Styles = Styles::StyleBasicColor(BasicColor { fg: 97, bg: 107 }); - -// -#[derive(Debug, Clone)] -pub struct PaletteColor { - pub index: u8, -} - -impl Stylify for PaletteColor { - fn make_styles(&self, paint_type: Option<&PaintType>) -> String { - let paint_type = paint_type.unwrap_or(&PaintType::FG); - format!( - "{};5;{}", - match paint_type { - PaintType::FG => "38", - PaintType::BG => "48", - }, - self.index - ) - } -} -#[derive(Debug, Clone)] -pub struct Rgb { - pub r: u8, - pub g: u8, - pub b: u8, -} - -impl Stylify for Rgb { - fn make_styles(&self, paint_type: Option<&PaintType>) -> String { - let paint_type = paint_type.unwrap_or(&PaintType::FG); - format!( - "{};2;{};{};{}", - match paint_type { - PaintType::FG => "38", - PaintType::BG => "48", - }, - self.r, - self.g, - self.b - ) - } -} - -// ======================================================================= - -#[cfg(test)] -mod test { - use super::*; - - #[test] - fn black_colors() { - let black = BasicColor { fg: 30, bg: 40 }; - assert_eq!(30, black.fg); - assert_eq!(40, black.bg) - } - - #[test] - fn cyan_colors() { - let cyan = BasicColor { fg: 36, bg: 46 }; - assert_eq!(36, cyan.fg); - assert_eq!(46, cyan.bg) - } - - #[test] - fn paint_yellow_foreground() { - let painted_fg = YELLOW.make_styles(None); - - assert_eq!("33", painted_fg) - } - - #[test] - fn paint_magenta_background() { - let painted_bg = MAGENTA.make_styles(Some(&PaintType::BG)); - - assert_eq!("45", painted_bg) - } - - #[test] - fn black_palette_color() { - let standard_black = PaletteColor { index: 0 }; - assert_eq!(0, standard_black.index) - } - - #[test] - fn gray_scale_palette_color() { - let gray_scale = PaletteColor { index: 243 }; - assert_eq!(243, gray_scale.index) - } - - #[test] - fn palette_paint_green_fg() { - let green = PaletteColor { index: 118 }; - let painted_fg = green.make_styles(None); - assert_eq!("38;5;118", painted_fg) - } - - #[test] - fn palette_paint_blue_bg() { - let blue = PaletteColor { index: 33 }; - let painted_bg = blue.make_styles(Some(&PaintType::BG)); - assert_eq!("48;5;33", painted_bg) - } - - #[test] - fn red_rgb_color() { - let red = Rgb { r: 255, g: 0, b: 0 }; - assert_eq!(255, red.r); - assert_eq!(0, red.g); - assert_eq!(0, red.b) - } - - #[test] - fn salmon_rgb_color() { - let salmon = Rgb { r: 250, g: 128, b: 114 }; - assert_eq!(250, salmon.r); - assert_eq!(128, salmon.g); - assert_eq!(114, salmon.b) - } - - #[test] - fn rgb_paint_purple_fg() { - let purple = Rgb { r: 126, g: 50, b: 219 }; - let painted_fg = purple.make_styles(None); - assert_eq!("38;2;126;50;219", painted_fg) - } - - #[test] - fn rgb_paint_orange_bg() { - let orange = Rgb { r: 219, g: 132, b: 50 }; - let painted_bg = orange.make_styles(Some(&PaintType::BG)); - assert_eq!("48;2;219;132;50", painted_bg) - } -} diff --git a/src/lib.rs b/src/lib.rs index 94e231c..66c07e8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,7 @@ mod ansi_escape_code; - +mod styled_text; +mod styles; // ======================================================================= + +pub use styled_text::styled; +// use styled_text::StyledText; diff --git a/src/styled_text.rs b/src/styled_text.rs index 9da75f6..4ec73f2 100644 --- a/src/styled_text.rs +++ b/src/styled_text.rs @@ -1,34 +1,12 @@ use crate::{ ansi_escape_code::ANSIEscapeCode, - colors::{ - PaintType, - PaletteColor, - Rgb, + styles::{ + basic_color, + formatter, + paint_type::PaintType, + palette::PaletteColor, + rgb::Rgb, Styles, - BLACK, - BLUE, - BOLD, - BRIGHT_BLUE, - BRIGHT_CYAN, - BRIGHT_GREEN, - BRIGHT_MAGENTA, - BRIGHT_RED, - BRIGHT_WHITE, - BRIGHT_YELLOW, - CYAN, - FAINT, - GRAY, - GREEN, - ITALIC, - MAGENTA, - OVERLINE, - RAPID_BLINK, - RED, - RESET, - SLOW_BLINK, - UNDERLINE, - WHITE, - YELLOW, }, }; @@ -118,7 +96,9 @@ impl StyledText { .rev() .collect(); let start_codes = start_codes_list.join(""); - let end_codes = ANSIEscapeCode::new(&RESET.make_styles(Some(&default_paint_type))).code(); + let end_codes = ANSIEscapeCode::new( + &formatter::RESET.make_styles(Some(&default_paint_type)) + ).code(); format!("{}{}{}", start_codes, self.text, end_codes) } @@ -146,124 +126,124 @@ impl StyledText { } pub fn black(&mut self) -> &mut Self { - self.start_styles.push(BLACK); + self.start_styles.push(basic_color::BLACK); self } pub fn red(&mut self) -> &mut Self { - self.start_styles.push(RED); + self.start_styles.push(basic_color::RED); self } pub fn green(&mut self) -> &mut Self { - self.start_styles.push(GREEN); + self.start_styles.push(basic_color::GREEN); self } pub fn yellow(&mut self) -> &mut Self { - self.start_styles.push(YELLOW); + self.start_styles.push(basic_color::YELLOW); self } pub fn blue(&mut self) -> &mut Self { - self.start_styles.push(BLUE); + self.start_styles.push(basic_color::BLUE); self } pub fn magenta(&mut self) -> &mut Self { - self.start_styles.push(MAGENTA); + self.start_styles.push(basic_color::MAGENTA); self } pub fn cyan(&mut self) -> &mut Self { - self.start_styles.push(CYAN); + self.start_styles.push(basic_color::CYAN); self } pub fn white(&mut self) -> &mut Self { - self.start_styles.push(WHITE); + self.start_styles.push(basic_color::WHITE); self } pub fn gray(&mut self) -> &mut Self { - self.start_styles.push(GRAY); + self.start_styles.push(basic_color::GRAY); self } pub fn bright_red(&mut self) -> &mut Self { - self.start_styles.push(BRIGHT_RED); + self.start_styles.push(basic_color::BRIGHT_RED); self } pub fn bright_green(&mut self) -> &mut Self { - self.start_styles.push(BRIGHT_GREEN); + self.start_styles.push(basic_color::BRIGHT_GREEN); self } pub fn bright_yellow(&mut self) -> &mut Self { - self.start_styles.push(BRIGHT_YELLOW); + self.start_styles.push(basic_color::BRIGHT_YELLOW); self } pub fn bright_blue(&mut self) -> &mut Self { - self.start_styles.push(BRIGHT_BLUE); + self.start_styles.push(basic_color::BRIGHT_BLUE); self } pub fn bright_magenta(&mut self) -> &mut Self { - self.start_styles.push(BRIGHT_MAGENTA); + self.start_styles.push(basic_color::BRIGHT_MAGENTA); self } pub fn bright_cyan(&mut self) -> &mut Self { - self.start_styles.push(BRIGHT_CYAN); + self.start_styles.push(basic_color::BRIGHT_CYAN); self } pub fn bright_white(&mut self) -> &mut Self { - self.start_styles.push(BRIGHT_WHITE); + self.start_styles.push(basic_color::BRIGHT_WHITE); self } // formatters pub fn reset(&mut self) -> &mut Self { - self.start_styles.push(RESET); + self.start_styles.push(formatter::RESET); self } pub fn bold(&mut self) -> &mut Self { - self.start_styles.push(BOLD); + self.start_styles.push(formatter::BOLD); self } pub fn faint(&mut self) -> &mut Self { - self.start_styles.push(FAINT); + self.start_styles.push(formatter::FAINT); self } pub fn italic(&mut self) -> &mut Self { - self.start_styles.push(ITALIC); + self.start_styles.push(formatter::ITALIC); self } pub fn underline(&mut self) -> &mut Self { - self.start_styles.push(UNDERLINE); + self.start_styles.push(formatter::UNDERLINE); self } pub fn slow_blink(&mut self) -> &mut Self { - self.start_styles.push(SLOW_BLINK); + self.start_styles.push(formatter::SLOW_BLINK); self } pub fn rapid_blink(&mut self) -> &mut Self { - self.start_styles.push(RAPID_BLINK); + self.start_styles.push(formatter::RAPID_BLINK); self } pub fn overline(&mut self) -> &mut Self { - self.start_styles.push(OVERLINE); + self.start_styles.push(formatter::OVERLINE); self } } diff --git a/src/styles.rs b/src/styles.rs new file mode 100644 index 0000000..9f8f29d --- /dev/null +++ b/src/styles.rs @@ -0,0 +1,40 @@ +use basic_color::BasicColor; +use formatter::Formatter; +use paint_type::PaintType; +use palette::PaletteColor; +use rgb::Rgb; + +// ======================================================================= + +pub mod paint_type; +pub mod formatter; +pub mod basic_color; +pub mod rgb; +pub mod palette; + +// ======================================================================= + +#[derive(Debug, Clone)] +pub enum Styles { + StyleRgb(Rgb), + StyleBasicColor(BasicColor), + StylePaletteColor(PaletteColor), + StylePaintType(PaintType), + StyleFormatter(Formatter), +} + +impl Styles { + pub fn make_styles(&self, paint_type: Option<&PaintType>) -> String { + match self { + Styles::StyleBasicColor(c) => c.make_styles(paint_type), + Styles::StylePaintType(c) => c.make_styles(paint_type), + Styles::StylePaletteColor(c) => c.make_styles(paint_type), + Styles::StyleRgb(c) => c.make_styles(paint_type), + Styles::StyleFormatter(c) => c.make_styles(paint_type), + } + } +} + +pub trait Stylify { + fn make_styles(&self, paint_type: Option<&PaintType>) -> String; +} diff --git a/src/styles/basic_color.rs b/src/styles/basic_color.rs new file mode 100644 index 0000000..791e581 --- /dev/null +++ b/src/styles/basic_color.rs @@ -0,0 +1,37 @@ +use super::{ paint_type::PaintType, Styles, Stylify }; + +// ======================================================================= + +#[derive(Debug, Clone)] +pub struct BasicColor { + fg: u8, + bg: u8, +} + +impl Stylify for BasicColor { + /// If the `is_foreground` was None it's assume as foreground + fn make_styles(&self, paint_type: Option<&PaintType>) -> String { + let paint_type = paint_type.unwrap_or(&PaintType::FG); + format!("{}", match paint_type { + PaintType::FG => self.fg, + PaintType::BG => self.bg, + }) + } +} + +pub const BLACK: Styles = Styles::StyleBasicColor(BasicColor { fg: 30, bg: 40 }); +pub const RED: Styles = Styles::StyleBasicColor(BasicColor { fg: 31, bg: 41 }); +pub const GREEN: Styles = Styles::StyleBasicColor(BasicColor { fg: 32, bg: 42 }); +pub const YELLOW: Styles = Styles::StyleBasicColor(BasicColor { fg: 33, bg: 43 }); +pub const BLUE: Styles = Styles::StyleBasicColor(BasicColor { fg: 34, bg: 44 }); +pub const MAGENTA: Styles = Styles::StyleBasicColor(BasicColor { fg: 35, bg: 45 }); +pub const CYAN: Styles = Styles::StyleBasicColor(BasicColor { fg: 36, bg: 46 }); +pub const WHITE: Styles = Styles::StyleBasicColor(BasicColor { fg: 37, bg: 47 }); +pub const GRAY: Styles = Styles::StyleBasicColor(BasicColor { fg: 90, bg: 10 }); +pub const BRIGHT_RED: Styles = Styles::StyleBasicColor(BasicColor { fg: 91, bg: 101 }); +pub const BRIGHT_GREEN: Styles = Styles::StyleBasicColor(BasicColor { fg: 92, bg: 102 }); +pub const BRIGHT_YELLOW: Styles = Styles::StyleBasicColor(BasicColor { fg: 93, bg: 103 }); +pub const BRIGHT_BLUE: Styles = Styles::StyleBasicColor(BasicColor { fg: 94, bg: 104 }); +pub const BRIGHT_MAGENTA: Styles = Styles::StyleBasicColor(BasicColor { fg: 95, bg: 105 }); +pub const BRIGHT_CYAN: Styles = Styles::StyleBasicColor(BasicColor { fg: 96, bg: 106 }); +pub const BRIGHT_WHITE: Styles = Styles::StyleBasicColor(BasicColor { fg: 97, bg: 107 }); diff --git a/src/styles/formatter.rs b/src/styles/formatter.rs new file mode 100644 index 0000000..0e9e9b6 --- /dev/null +++ b/src/styles/formatter.rs @@ -0,0 +1,23 @@ +use super::{ paint_type::PaintType, Styles, Stylify }; + +// ======================================================================= + +#[derive(Debug, Clone)] +pub struct Formatter { + n: u8, +} + +impl Stylify for Formatter { + fn make_styles(&self, _paint_type: Option<&PaintType>) -> String { + format!("{}", self.n) + } +} + +pub const RESET: Styles = Styles::StyleFormatter(Formatter { n: 0 }); +pub const BOLD: Styles = Styles::StyleFormatter(Formatter { n: 1 }); +pub const FAINT: Styles = Styles::StyleFormatter(Formatter { n: 2 }); +pub const ITALIC: Styles = Styles::StyleFormatter(Formatter { n: 3 }); +pub const UNDERLINE: Styles = Styles::StyleFormatter(Formatter { n: 4 }); +pub const SLOW_BLINK: Styles = Styles::StyleFormatter(Formatter { n: 5 }); +pub const RAPID_BLINK: Styles = Styles::StyleFormatter(Formatter { n: 6 }); +pub const OVERLINE: Styles = Styles::StyleFormatter(Formatter { n: 53 }); diff --git a/src/styles/paint_type.rs b/src/styles/paint_type.rs new file mode 100644 index 0000000..ad680bd --- /dev/null +++ b/src/styles/paint_type.rs @@ -0,0 +1,15 @@ +use super::Stylify; + +// ======================================================================= + +#[derive(Debug, Clone)] +pub enum PaintType { + FG, + BG, +} + +impl Stylify for PaintType { + fn make_styles(&self, _paint_type: Option<&PaintType>) -> String { + String::new() + } +} diff --git a/src/styles/palette.rs b/src/styles/palette.rs new file mode 100644 index 0000000..1ea9fd1 --- /dev/null +++ b/src/styles/palette.rs @@ -0,0 +1,22 @@ +use super::{ paint_type::PaintType, Stylify }; + +// ======================================================================= + +#[derive(Debug, Clone)] +pub struct PaletteColor { + pub index: u8, +} + +impl Stylify for PaletteColor { + fn make_styles(&self, paint_type: Option<&PaintType>) -> String { + let paint_type = paint_type.unwrap_or(&PaintType::FG); + format!( + "{};5;{}", + match paint_type { + PaintType::FG => "38", + PaintType::BG => "48", + }, + self.index + ) + } +} diff --git a/src/styles/rgb.rs b/src/styles/rgb.rs new file mode 100644 index 0000000..f871407 --- /dev/null +++ b/src/styles/rgb.rs @@ -0,0 +1,26 @@ +use super::{ paint_type::PaintType, Stylify }; + +// ======================================================================= + +#[derive(Debug, Clone)] +pub struct Rgb { + pub r: u8, + pub g: u8, + pub b: u8, +} + +impl Stylify for Rgb { + fn make_styles(&self, paint_type: Option<&PaintType>) -> String { + let paint_type = paint_type.unwrap_or(&PaintType::FG); + format!( + "{};2;{};{};{}", + match paint_type { + PaintType::FG => "38", + PaintType::BG => "48", + }, + self.r, + self.g, + self.b + ) + } +} diff --git a/src/traits.rs b/src/traits.rs deleted file mode 100644 index 2302d2e..0000000 --- a/src/traits.rs +++ /dev/null @@ -1,5 +0,0 @@ -use crate::colors::PaintType; - -pub trait Stylify { - fn make_styles(&self, paint_type: Option<&PaintType>) -> String; -} From 95fb2161a0609707c14d1e4ff95c8083641bc6e0 Mon Sep 17 00:00:00 2001 From: syaw0 Date: Tue, 5 Nov 2024 10:28:31 +0330 Subject: [PATCH 29/51] refactor: Move the styled_text module to lib and remove the styled_text module --- src/lib.rs | 256 ++++++++++++++++++++++++++++++++++++- src/styled_text.rs | 305 --------------------------------------------- 2 files changed, 253 insertions(+), 308 deletions(-) delete mode 100644 src/styled_text.rs diff --git a/src/lib.rs b/src/lib.rs index 66c07e8..1a96047 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,7 +1,257 @@ +//! # Vitalux: Rich Api For Colorize Terminal +//! +//! + mod ansi_escape_code; -mod styled_text; mod styles; + // ======================================================================= +use crate::{ + ansi_escape_code::ANSIEscapeCode, + styles::{ + basic_color, + formatter, + paint_type::PaintType, + palette::PaletteColor, + rgb::Rgb, + Styles, + }, +}; + +// ======================================================================= + +/// Creates a styled text string with the given text and styles. +/// +/// This function returns a `StyledText` object that can be customized with various styles, +/// colors, and effects. The resulting styled text can be printed or used in other contexts. +/// +/// # Examples +/// +/// ``` +/// use vitalux::styled; +/// +/// let txt = styled("Happy Day!") +/// .rgb(204, 182, 122) +/// .italic() +/// .rapid_blink() +/// .bg() +/// .rgb(74, 56, 7) +/// .fg() +/// .paint(); +/// println!("{txt}"); +/// ``` +/// +/// # Styles +/// +/// The following styles can be applied to the text: +/// +/// * `rgb(r, g, b)`: Sets the text color to the given RGB values. +/// * `italic()`: Sets the text to italic. +/// * `rapid_blink()`: Sets the text to rapidly blink. +/// * `bg()`: Sets the background color. +/// * `fg()`: Sets the foreground color. +/// +/// # Colors +/// +/// The following colors can be used with the `rgb` method: +/// +/// * `rgb(r, g, b)`: Sets the color to the given RGB values. +/// +/// # Effects +/// +/// The following effects can be applied to the text: +/// +/// * `rapid_blink()`: Sets the text to rapidly blink. +/// +/// # Returns +/// +/// A `StyledText` object that can be printed or used in other contexts. +pub fn styled(text: &str) -> StyledText { + StyledText::new(text.to_string()) +} + +pub struct StyledText { + text: String, + start_styles: Vec, +} + +impl StyledText { + fn new(text: String) -> Self { + // we should use Formatter::reset() + // let reset_ansi = ANSIEscapeCode::new("0"); + StyledText { + text, + start_styles: vec![], + } + } + + pub fn paint(&mut self) -> String { + let mut default_paint_type = PaintType::FG; + + let start_codes_list: Vec = self.start_styles + .iter() + .rev() + .filter_map(|s| { + if let Styles::StylePaintType(p) = s { + default_paint_type = p.clone(); + return None; + } + let t = s.make_styles(Some(&default_paint_type)); + Some(ANSIEscapeCode::new(t.as_str()).code()) + }) + .collect::>() + .into_iter() + .rev() + .collect(); + let start_codes = start_codes_list.join(""); + let end_codes = ANSIEscapeCode::new( + &formatter::RESET.make_styles(Some(&default_paint_type)) + ).code(); + + format!("{}{}{}", start_codes, self.text, end_codes) + } + + pub fn fg(&mut self) -> &mut Self { + self.start_styles.push(Styles::StylePaintType(PaintType::FG)); + self + } + + pub fn bg(&mut self) -> &mut Self { + self.start_styles.push(Styles::StylePaintType(PaintType::BG)); + self + } + + // Colors + + pub fn rgb(&mut self, r: u8, g: u8, b: u8) -> &mut Self { + self.start_styles.push(Styles::StyleRgb(Rgb { r, g, b })); + self + } + + pub fn palette(&mut self, index: u8) -> &mut Self { + self.start_styles.push(Styles::StylePaletteColor(PaletteColor { index })); + self + } + + pub fn black(&mut self) -> &mut Self { + self.start_styles.push(basic_color::BLACK); + self + } + + pub fn red(&mut self) -> &mut Self { + self.start_styles.push(basic_color::RED); + self + } + + pub fn green(&mut self) -> &mut Self { + self.start_styles.push(basic_color::GREEN); + self + } + + pub fn yellow(&mut self) -> &mut Self { + self.start_styles.push(basic_color::YELLOW); + self + } + + pub fn blue(&mut self) -> &mut Self { + self.start_styles.push(basic_color::BLUE); + self + } + + pub fn magenta(&mut self) -> &mut Self { + self.start_styles.push(basic_color::MAGENTA); + self + } + + pub fn cyan(&mut self) -> &mut Self { + self.start_styles.push(basic_color::CYAN); + self + } + + pub fn white(&mut self) -> &mut Self { + self.start_styles.push(basic_color::WHITE); + self + } + + pub fn gray(&mut self) -> &mut Self { + self.start_styles.push(basic_color::GRAY); + self + } + + pub fn bright_red(&mut self) -> &mut Self { + self.start_styles.push(basic_color::BRIGHT_RED); + self + } + + pub fn bright_green(&mut self) -> &mut Self { + self.start_styles.push(basic_color::BRIGHT_GREEN); + self + } + + pub fn bright_yellow(&mut self) -> &mut Self { + self.start_styles.push(basic_color::BRIGHT_YELLOW); + self + } + + pub fn bright_blue(&mut self) -> &mut Self { + self.start_styles.push(basic_color::BRIGHT_BLUE); + self + } + + pub fn bright_magenta(&mut self) -> &mut Self { + self.start_styles.push(basic_color::BRIGHT_MAGENTA); + self + } + + pub fn bright_cyan(&mut self) -> &mut Self { + self.start_styles.push(basic_color::BRIGHT_CYAN); + self + } + + pub fn bright_white(&mut self) -> &mut Self { + self.start_styles.push(basic_color::BRIGHT_WHITE); + self + } + + // Formatters + + pub fn reset(&mut self) -> &mut Self { + self.start_styles.push(formatter::RESET); + self + } + + pub fn bold(&mut self) -> &mut Self { + self.start_styles.push(formatter::BOLD); + self + } + + pub fn faint(&mut self) -> &mut Self { + self.start_styles.push(formatter::FAINT); + self + } + + pub fn italic(&mut self) -> &mut Self { + self.start_styles.push(formatter::ITALIC); + self + } + + pub fn underline(&mut self) -> &mut Self { + self.start_styles.push(formatter::UNDERLINE); + self + } + + pub fn slow_blink(&mut self) -> &mut Self { + self.start_styles.push(formatter::SLOW_BLINK); + self + } + + pub fn rapid_blink(&mut self) -> &mut Self { + self.start_styles.push(formatter::RAPID_BLINK); + self + } -pub use styled_text::styled; -// use styled_text::StyledText; + pub fn overline(&mut self) -> &mut Self { + self.start_styles.push(formatter::OVERLINE); + self + } +} diff --git a/src/styled_text.rs b/src/styled_text.rs deleted file mode 100644 index 4ec73f2..0000000 --- a/src/styled_text.rs +++ /dev/null @@ -1,305 +0,0 @@ -use crate::{ - ansi_escape_code::ANSIEscapeCode, - styles::{ - basic_color, - formatter, - paint_type::PaintType, - palette::PaletteColor, - rgb::Rgb, - Styles, - }, -}; - -// ======================================================================= - -/// Creates a styled text string with the given text and styles. -/// -/// This function returns a `StyledText` object that can be customized with various styles, -/// colors, and effects. The resulting styled text can be printed or used in other contexts. -/// -/// # Examples -/// -/// ``` -/// use vitalux::styled; -/// -/// let txt = styled("Happy Day!") -/// .rgb(204, 182, 122) -/// .italic() -/// .rapid_blink() -/// .bg() -/// .rgb(74, 56, 7) -/// .fg() -/// .paint(); -/// println!("{txt}"); -/// ``` -/// -/// # Styles -/// -/// The following styles can be applied to the text: -/// -/// * `rgb(r, g, b)`: Sets the text color to the given RGB values. -/// * `italic()`: Sets the text to italic. -/// * `rapid_blink()`: Sets the text to rapidly blink. -/// * `bg()`: Sets the background color. -/// * `fg()`: Sets the foreground color. -/// -/// # Colors -/// -/// The following colors can be used with the `rgb` method: -/// -/// * `rgb(r, g, b)`: Sets the color to the given RGB values. -/// -/// # Effects -/// -/// The following effects can be applied to the text: -/// -/// * `rapid_blink()`: Sets the text to rapidly blink. -/// -/// # Returns -/// -/// A `StyledText` object that can be printed or used in other contexts. -pub fn styled(text: &str) -> StyledText { - StyledText::new(text.to_string()) -} - -pub struct StyledText { - text: String, - start_styles: Vec, -} - -impl StyledText { - fn new(text: String) -> Self { - // we should use Formatter::reset() - // let reset_ansi = ANSIEscapeCode::new("0"); - StyledText { - text, - start_styles: vec![], - } - } - - pub fn paint(&mut self) -> String { - let mut default_paint_type = PaintType::FG; - - let start_codes_list: Vec = self.start_styles - .iter() - .rev() - .filter_map(|s| { - if let Styles::StylePaintType(p) = s { - default_paint_type = p.clone(); - return None; - } - let t = s.make_styles(Some(&default_paint_type)); - Some(ANSIEscapeCode::new(t.as_str()).code()) - }) - .collect::>() - .into_iter() - .rev() - .collect(); - let start_codes = start_codes_list.join(""); - let end_codes = ANSIEscapeCode::new( - &formatter::RESET.make_styles(Some(&default_paint_type)) - ).code(); - - format!("{}{}{}", start_codes, self.text, end_codes) - } - - pub fn fg(&mut self) -> &mut Self { - self.start_styles.push(Styles::StylePaintType(PaintType::FG)); - self - } - - pub fn bg(&mut self) -> &mut Self { - self.start_styles.push(Styles::StylePaintType(PaintType::BG)); - self - } - - // Colors - - pub fn rgb(&mut self, r: u8, g: u8, b: u8) -> &mut Self { - self.start_styles.push(Styles::StyleRgb(Rgb { r, g, b })); - self - } - - pub fn palette(&mut self, index: u8) -> &mut Self { - self.start_styles.push(Styles::StylePaletteColor(PaletteColor { index })); - self - } - - pub fn black(&mut self) -> &mut Self { - self.start_styles.push(basic_color::BLACK); - self - } - - pub fn red(&mut self) -> &mut Self { - self.start_styles.push(basic_color::RED); - self - } - - pub fn green(&mut self) -> &mut Self { - self.start_styles.push(basic_color::GREEN); - self - } - - pub fn yellow(&mut self) -> &mut Self { - self.start_styles.push(basic_color::YELLOW); - self - } - - pub fn blue(&mut self) -> &mut Self { - self.start_styles.push(basic_color::BLUE); - self - } - - pub fn magenta(&mut self) -> &mut Self { - self.start_styles.push(basic_color::MAGENTA); - self - } - - pub fn cyan(&mut self) -> &mut Self { - self.start_styles.push(basic_color::CYAN); - self - } - - pub fn white(&mut self) -> &mut Self { - self.start_styles.push(basic_color::WHITE); - self - } - - pub fn gray(&mut self) -> &mut Self { - self.start_styles.push(basic_color::GRAY); - self - } - - pub fn bright_red(&mut self) -> &mut Self { - self.start_styles.push(basic_color::BRIGHT_RED); - self - } - - pub fn bright_green(&mut self) -> &mut Self { - self.start_styles.push(basic_color::BRIGHT_GREEN); - self - } - - pub fn bright_yellow(&mut self) -> &mut Self { - self.start_styles.push(basic_color::BRIGHT_YELLOW); - self - } - - pub fn bright_blue(&mut self) -> &mut Self { - self.start_styles.push(basic_color::BRIGHT_BLUE); - self - } - - pub fn bright_magenta(&mut self) -> &mut Self { - self.start_styles.push(basic_color::BRIGHT_MAGENTA); - self - } - - pub fn bright_cyan(&mut self) -> &mut Self { - self.start_styles.push(basic_color::BRIGHT_CYAN); - self - } - - pub fn bright_white(&mut self) -> &mut Self { - self.start_styles.push(basic_color::BRIGHT_WHITE); - self - } - - // formatters - - pub fn reset(&mut self) -> &mut Self { - self.start_styles.push(formatter::RESET); - self - } - - pub fn bold(&mut self) -> &mut Self { - self.start_styles.push(formatter::BOLD); - self - } - - pub fn faint(&mut self) -> &mut Self { - self.start_styles.push(formatter::FAINT); - self - } - - pub fn italic(&mut self) -> &mut Self { - self.start_styles.push(formatter::ITALIC); - self - } - - pub fn underline(&mut self) -> &mut Self { - self.start_styles.push(formatter::UNDERLINE); - self - } - - pub fn slow_blink(&mut self) -> &mut Self { - self.start_styles.push(formatter::SLOW_BLINK); - self - } - - pub fn rapid_blink(&mut self) -> &mut Self { - self.start_styles.push(formatter::RAPID_BLINK); - self - } - - pub fn overline(&mut self) -> &mut Self { - self.start_styles.push(formatter::OVERLINE); - self - } -} - -#[cfg(test)] -mod test { - use super::*; - - #[test] - fn white_fg_black_bg() { - let raw_text = "I'm So Happy"; - let styled_text = styled(raw_text).white().bg().black().fg().paint(); - assert_eq!(styled_text, "\x1b[47m\x1b[30mI'm So Happy\x1b[0m"); - } - - #[test] - fn blue_fg_bright_cyan_bg() { - let raw_text = "Silence is power"; - let styled_text = styled(raw_text).blue().fg().bright_cyan().bg().paint(); - assert_eq!(styled_text, "\x1b[34m\x1b[106mSilence is power\x1b[0m"); - } - - #[test] - fn test_with_one_paint_type() { - let no: Vec = styled("Hello there") - .bright_blue() - .red() - .bg() - .start_styles.iter() - .filter(|s| { - match s { - Styles::StylePaintType(_) => true, - _ => false, - } - }) - .cloned() - .collect(); - - assert_eq!(no.len(), 1) - } - - #[test] - fn test_with_zero_paint_type() { - let no: Vec = styled("Hello there") - .bright_blue() - .red() - .start_styles.iter() - .filter(|s| { - match s { - Styles::StylePaintType(_) => true, - _ => false, - } - }) - .cloned() - .collect(); - - assert_eq!(no.len(), 0) - } -} From d4beec4c6a331a3104e07ea997bec63e929cb90e Mon Sep 17 00:00:00 2001 From: syaw0 Date: Wed, 6 Nov 2024 09:25:48 +0330 Subject: [PATCH 30/51] refactor: rename the ansi_escape_code to ansi_code --- src/{ansi_escape_code.rs => ansi_code.rs} | 2 +- src/lib.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) rename src/{ansi_escape_code.rs => ansi_code.rs} (96%) diff --git a/src/ansi_escape_code.rs b/src/ansi_code.rs similarity index 96% rename from src/ansi_escape_code.rs rename to src/ansi_code.rs index 110b29c..bb1fea8 100644 --- a/src/ansi_escape_code.rs +++ b/src/ansi_code.rs @@ -14,7 +14,7 @@ impl ANSIEscapeCode { // ======================================================================= #[cfg(test)] -mod ansi_escape_code_test { +mod tests { use super::*; #[test] diff --git a/src/lib.rs b/src/lib.rs index 1a96047..fdd1d1f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,12 +2,12 @@ //! //! -mod ansi_escape_code; +mod ansi_code; mod styles; // ======================================================================= use crate::{ - ansi_escape_code::ANSIEscapeCode, + ansi_code::ANSIEscapeCode, styles::{ basic_color, formatter, From ff9e5044d85bb5db15d57f0bcb6d1699d8866814 Mon Sep 17 00:00:00 2001 From: syaw0 Date: Wed, 6 Nov 2024 09:37:34 +0330 Subject: [PATCH 31/51] refactor: Use `Macros` to create basic colors --- src/styles/basic_color.rs | 59 ++++++++++++++++++++++++++++----------- 1 file changed, 43 insertions(+), 16 deletions(-) diff --git a/src/styles/basic_color.rs b/src/styles/basic_color.rs index 791e581..ec0df50 100644 --- a/src/styles/basic_color.rs +++ b/src/styles/basic_color.rs @@ -19,19 +19,46 @@ impl Stylify for BasicColor { } } -pub const BLACK: Styles = Styles::StyleBasicColor(BasicColor { fg: 30, bg: 40 }); -pub const RED: Styles = Styles::StyleBasicColor(BasicColor { fg: 31, bg: 41 }); -pub const GREEN: Styles = Styles::StyleBasicColor(BasicColor { fg: 32, bg: 42 }); -pub const YELLOW: Styles = Styles::StyleBasicColor(BasicColor { fg: 33, bg: 43 }); -pub const BLUE: Styles = Styles::StyleBasicColor(BasicColor { fg: 34, bg: 44 }); -pub const MAGENTA: Styles = Styles::StyleBasicColor(BasicColor { fg: 35, bg: 45 }); -pub const CYAN: Styles = Styles::StyleBasicColor(BasicColor { fg: 36, bg: 46 }); -pub const WHITE: Styles = Styles::StyleBasicColor(BasicColor { fg: 37, bg: 47 }); -pub const GRAY: Styles = Styles::StyleBasicColor(BasicColor { fg: 90, bg: 10 }); -pub const BRIGHT_RED: Styles = Styles::StyleBasicColor(BasicColor { fg: 91, bg: 101 }); -pub const BRIGHT_GREEN: Styles = Styles::StyleBasicColor(BasicColor { fg: 92, bg: 102 }); -pub const BRIGHT_YELLOW: Styles = Styles::StyleBasicColor(BasicColor { fg: 93, bg: 103 }); -pub const BRIGHT_BLUE: Styles = Styles::StyleBasicColor(BasicColor { fg: 94, bg: 104 }); -pub const BRIGHT_MAGENTA: Styles = Styles::StyleBasicColor(BasicColor { fg: 95, bg: 105 }); -pub const BRIGHT_CYAN: Styles = Styles::StyleBasicColor(BasicColor { fg: 96, bg: 106 }); -pub const BRIGHT_WHITE: Styles = Styles::StyleBasicColor(BasicColor { fg: 97, bg: 107 }); +macro_rules! color_code { + ($name:ident, { fg: $fg:expr, bg: $bg:expr }) => { + pub const $name:Styles = Styles::StyleBasicColor(BasicColor { fg: $fg, bg: $bg }); + }; +} + +color_code!(BLACK,{fg: 30, bg: 40 }); +color_code!(RED,{fg: 31, bg: 41}); +color_code!(GREEN,{ fg: 32, bg: 42 }); +color_code!(YELLOW,{ fg: 33, bg: 43 }); +color_code!(BLUE,{fg: 34, bg: 44}); +color_code!(MAGENTA,{ fg: 35, bg: 45}); +color_code!(CYAN,{fg:36,bg:46}); +color_code!(WHITE,{fg:37,bg:47}); +color_code!(GRAY,{fg:90,bg:100}); +color_code!(BRIGHT_RED,{fg:91,bg:101}); +color_code!(BRIGHT_GREEN,{fg:92,bg:102}); +color_code!(BRIGHT_YELLOW,{fg:93,bg:103}); +color_code!(BRIGHT_BLUE,{fg:94,bg:104}); +color_code!(BRIGHT_MAGENTA,{fg:95,bg:105}); +color_code!(BRIGHT_CYAN,{fg:96,bg:106}); +color_code!(BRIGHT_WHITE,{fg:97,bg:107}); + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn black_color() { + match BLACK { + Styles::StyleBasicColor(BasicColor { fg: 30, bg: 40 }) => assert!(true), + _ => panic!("It's not a `Black` color! black color should have fg:30 and bg:40"), + } + } + + #[test] + fn red_color() { + match RED { + Styles::StyleBasicColor(BasicColor { fg: 31, bg: 41 }) => assert!(true), + _ => panic!("It's not a `Red` color! red color should have fg:31 and bg:41"), + } + } +} From 4b4126e89bc7078af0f6970950cf34d07ca0b7b2 Mon Sep 17 00:00:00 2001 From: syaw0 Date: Wed, 6 Nov 2024 10:37:36 +0330 Subject: [PATCH 32/51] test(basic_color.rs): Write test for coverage all of the module --- src/styles/basic_color.rs | 87 +++++++++++++++++++++++++++++++++++---- 1 file changed, 78 insertions(+), 9 deletions(-) diff --git a/src/styles/basic_color.rs b/src/styles/basic_color.rs index ec0df50..8c6204c 100644 --- a/src/styles/basic_color.rs +++ b/src/styles/basic_color.rs @@ -47,18 +47,87 @@ mod tests { use super::*; #[test] - fn black_color() { - match BLACK { - Styles::StyleBasicColor(BasicColor { fg: 30, bg: 40 }) => assert!(true), - _ => panic!("It's not a `Black` color! black color should have fg:30 and bg:40"), - } + fn test_make_style_fg() { + let color = BasicColor { fg: 30, bg: 40 }; + let styles = color.make_styles(Some(&PaintType::FG)); + assert_eq!(styles, "30") + } + + #[test] + fn test_make_style_default_fg() { + let color = BasicColor { fg: 34, bg: 44 }; + let styles = color.make_styles(None); + assert_eq!(styles, "34") + } + + #[test] + fn test_make_style_bg() { + let color = BasicColor { fg: 30, bg: 40 }; + let styles = color.make_styles(Some(&PaintType::BG)); + assert_eq!(styles, "40") + } + + #[test] + fn test_fg_and_bg_values() { + let color = BasicColor { fg: 30, bg: 40 }; + let styles_fg = color.make_styles(Some(&PaintType::FG)); + let styles_bg = color.make_styles(Some(&PaintType::BG)); + assert_eq!(styles_fg, "30"); + assert_eq!(styles_bg, "40"); + } + + #[test] + fn test_fg_and_bg_values_with_none_paint_type() { + let color = BasicColor { fg: 30, bg: 40 }; + let styles_fg = color.make_styles(None); + let styles_bg = color.make_styles(Some(&PaintType::BG)); + assert_eq!(styles_fg, "30"); + assert_eq!(styles_bg, "40"); } #[test] - fn red_color() { - match RED { - Styles::StyleBasicColor(BasicColor { fg: 31, bg: 41 }) => assert!(true), - _ => panic!("It's not a `Red` color! red color should have fg:31 and bg:41"), + fn test_color_code_macro() { + color_code!(TEST_COLOR,{fg:100,bg:200}); + match TEST_COLOR { + Styles::StyleBasicColor(BasicColor { fg, bg }) => { + assert_eq!(fg, 100); + assert_eq!(bg, 200); + } + _ => panic!("TEST_COLOR is not a BasicColor"), } } + + macro_rules! color_test { + ($test_name:ident, $color_name:ident, $color:expr, $fg:expr, $bg:expr) => { + #[test] + fn $test_name(){ + match $color_name{ + Styles::StyleBasicColor(BasicColor{fg,bg})=>{ + assert_eq!(fg,$fg); + assert_eq!(bg,$bg); + }, + _=>{ + panic!("This color is not a basic color!"); + } + } + } + }; + } + + color_test!(black_color, BLACK, "Black", 30, 40); + color_test!(red_color, RED, "Red", 31, 41); + color_test!(green_color, GREEN, "Green", 32, 42); + color_test!(yellow_color, YELLOW, "Yellow", 33, 43); + color_test!(blue_color, BLUE, "Blue", 34, 44); + color_test!(magenta_color, MAGENTA, "Magenta", 35, 45); + color_test!(cyan_color, CYAN, "Cyan", 36, 46); + color_test!(white_color, WHITE, "White", 37, 47); + color_test!(gray_color, GRAY, "Gray", 90, 100); + color_test!(bright_red_color, BRIGHT_RED, "Bright Red", 91, 101); + color_test!(bright_green_color, BRIGHT_GREEN, "Bright Green", 92, 102); + color_test!(bright_yellow_color, BRIGHT_YELLOW, "Bright Yellow", 93, 103); + color_test!(bright_blue_color, BRIGHT_BLUE, "Bright Blue", 94, 104); + color_test!(bright_magenta_color, BRIGHT_MAGENTA, "Bright Magenta", 95, 105); + color_test!(bright_cyan_color, BRIGHT_CYAN, "Bright Cyan", 96, 106); + color_test!(bright_white_color, BRIGHT_WHITE, "Bright White", 97, 107); } From 8cabf4e0ddd1d020a6c205204177e8cd4cbdef30 Mon Sep 17 00:00:00 2001 From: syaw0 Date: Wed, 6 Nov 2024 10:43:05 +0330 Subject: [PATCH 33/51] doc(basic_color.rs): Write document for module --- src/styles/basic_color.rs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/styles/basic_color.rs b/src/styles/basic_color.rs index 8c6204c..40c65ec 100644 --- a/src/styles/basic_color.rs +++ b/src/styles/basic_color.rs @@ -2,14 +2,19 @@ use super::{ paint_type::PaintType, Styles, Stylify }; // ======================================================================= +/// A struct representing a basic color with foreground and background values. #[derive(Debug, Clone)] pub struct BasicColor { + /// The foreground color value. fg: u8, + /// The background color value. bg: u8, } impl Stylify for BasicColor { - /// If the `is_foreground` was None it's assume as foreground + /// Returns a string representation of the color style. + /// + /// If `paint_type` is `None`, the foreground color is assumed. fn make_styles(&self, paint_type: Option<&PaintType>) -> String { let paint_type = paint_type.unwrap_or(&PaintType::FG); format!("{}", match paint_type { @@ -19,6 +24,13 @@ impl Stylify for BasicColor { } } +/// A macro for generating color constants. +/// +/// Usage: +/// +/// ```rust +/// color_code!(MY_COLOR, { fg: 30, bg: 40 }); +/// ``` macro_rules! color_code { ($name:ident, { fg: $fg:expr, bg: $bg:expr }) => { pub const $name:Styles = Styles::StyleBasicColor(BasicColor { fg: $fg, bg: $bg }); From fbf1c1b913d6581216430a88a82de219688e337a Mon Sep 17 00:00:00 2001 From: syaw0 Date: Wed, 6 Nov 2024 10:48:20 +0330 Subject: [PATCH 34/51] refactor(formatter.rs): Write `Macro` to reduce code duplication --- src/styles/formatter.rs | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/src/styles/formatter.rs b/src/styles/formatter.rs index 0e9e9b6..980ab76 100644 --- a/src/styles/formatter.rs +++ b/src/styles/formatter.rs @@ -4,20 +4,26 @@ use super::{ paint_type::PaintType, Styles, Stylify }; #[derive(Debug, Clone)] pub struct Formatter { - n: u8, + code: u8, } impl Stylify for Formatter { fn make_styles(&self, _paint_type: Option<&PaintType>) -> String { - format!("{}", self.n) + format!("{}", self.code) } } -pub const RESET: Styles = Styles::StyleFormatter(Formatter { n: 0 }); -pub const BOLD: Styles = Styles::StyleFormatter(Formatter { n: 1 }); -pub const FAINT: Styles = Styles::StyleFormatter(Formatter { n: 2 }); -pub const ITALIC: Styles = Styles::StyleFormatter(Formatter { n: 3 }); -pub const UNDERLINE: Styles = Styles::StyleFormatter(Formatter { n: 4 }); -pub const SLOW_BLINK: Styles = Styles::StyleFormatter(Formatter { n: 5 }); -pub const RAPID_BLINK: Styles = Styles::StyleFormatter(Formatter { n: 6 }); -pub const OVERLINE: Styles = Styles::StyleFormatter(Formatter { n: 53 }); +macro_rules! formatter_code { + ($name:ident, $code:expr) => { + pub const $name: Styles = Styles::StyleFormatter(Formatter { code: $code }); + }; +} + +formatter_code!(RESET, 0); +formatter_code!(BOLD, 1); +formatter_code!(FAINT, 2); +formatter_code!(ITALIC, 3); +formatter_code!(UNDERLINE, 4); +formatter_code!(SLOW_BLINK, 5); +formatter_code!(RAPID_BLINK, 6); +formatter_code!(OVERLINE, 53); From 860c7a51589baeac31d2327ce8469e1684639304 Mon Sep 17 00:00:00 2001 From: syaw0 Date: Wed, 6 Nov 2024 11:04:16 +0330 Subject: [PATCH 35/51] fix(basic_color.rs): fix issue with document comment test for color_code macro --- src/styles/basic_color.rs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/styles/basic_color.rs b/src/styles/basic_color.rs index 40c65ec..707a894 100644 --- a/src/styles/basic_color.rs +++ b/src/styles/basic_color.rs @@ -25,12 +25,6 @@ impl Stylify for BasicColor { } /// A macro for generating color constants. -/// -/// Usage: -/// -/// ```rust -/// color_code!(MY_COLOR, { fg: 30, bg: 40 }); -/// ``` macro_rules! color_code { ($name:ident, { fg: $fg:expr, bg: $bg:expr }) => { pub const $name:Styles = Styles::StyleBasicColor(BasicColor { fg: $fg, bg: $bg }); From df4a75c8cdabac3878ae1fc871728a714aceadac Mon Sep 17 00:00:00 2001 From: syaw0 Date: Wed, 6 Nov 2024 11:12:50 +0330 Subject: [PATCH 36/51] test(formatter.rs): Write test for coverage module --- src/styles/formatter.rs | 80 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/src/styles/formatter.rs b/src/styles/formatter.rs index 980ab76..7bdc371 100644 --- a/src/styles/formatter.rs +++ b/src/styles/formatter.rs @@ -27,3 +27,83 @@ formatter_code!(UNDERLINE, 4); formatter_code!(SLOW_BLINK, 5); formatter_code!(RAPID_BLINK, 6); formatter_code!(OVERLINE, 53); + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn make_styles_fg() { + let formatter = Formatter { code: 22 }; + let styles = formatter.make_styles(Some(&PaintType::FG)); + assert_eq!(styles, "22") + } + + #[test] + fn make_styles_bg() { + let formatter = Formatter { code: 111 }; + let styles = formatter.make_styles(Some(&PaintType::BG)); + assert_eq!(styles, "111") + } + + #[test] + fn make_styles_default_paint_type() { + let formatter = Formatter { code: 31 }; + let styles = formatter.make_styles(None); + assert_eq!(styles, "31") + } + + #[test] + fn test_code_values() { + let formatter = Formatter { code: 90 }; + let styles_fg = formatter.make_styles(Some(&PaintType::FG)); + let styles_bg = formatter.make_styles(Some(&PaintType::BG)); + assert_eq!(styles_fg, "90"); + assert_eq!(styles_bg, "90"); + } + + #[test] + fn test_code_values_with_none_paint_type() { + let formatter = Formatter { code: 47 }; + let styles_fg = formatter.make_styles(None); + let styles_bg = formatter.make_styles(Some(&PaintType::BG)); + assert_eq!(styles_fg, "47"); + assert_eq!(styles_bg, "47"); + } + + #[test] + fn test_formatter_code_macro() { + formatter_code!(TEST_FORMATTER, 103); + match TEST_FORMATTER { + Styles::StyleFormatter(Formatter { code }) => { + assert_eq!(code, 103); + } + _ => panic!("TEST_FORMATTER is not a Formatter"), + } + } + + macro_rules! formatter_test { + ($test_name:ident, $formatter_name:ident, $code:expr) => { + #[test] + fn $test_name(){ + match $formatter_name{ + Styles::StyleFormatter(Formatter{code})=>{ + assert_eq!(code,$code); + }, + _=>{ + panic!("This formatter is not a Formatter!"); + } + } + } + }; + } + + formatter_test!(test_reset_formatter, RESET, 0); + formatter_test!(test_bold_formatter, BOLD, 1); + formatter_test!(test_faint_formatter, FAINT, 2); + formatter_test!(test_italic_formatter, ITALIC, 3); + formatter_test!(test_underline_formatter, UNDERLINE, 4); + formatter_test!(test_slow_blink_formatter, SLOW_BLINK, 5); + formatter_test!(test_rapid_blink_formatter, RAPID_BLINK, 6); + formatter_test!(test_overline_formatter, OVERLINE, 53); +} From 67b873d0b047215537c1973c3c222fb57a71c4cd Mon Sep 17 00:00:00 2001 From: syaw0 Date: Wed, 6 Nov 2024 11:15:26 +0330 Subject: [PATCH 37/51] doc(formatter.rs): Write document test for a module --- src/styles/formatter.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/styles/formatter.rs b/src/styles/formatter.rs index 7bdc371..13ffd07 100644 --- a/src/styles/formatter.rs +++ b/src/styles/formatter.rs @@ -2,17 +2,22 @@ use super::{ paint_type::PaintType, Styles, Stylify }; // ======================================================================= +/// A struct representing a Formatter with code value. #[derive(Debug, Clone)] pub struct Formatter { code: u8, } impl Stylify for Formatter { + /// Returns a string representation of the formatter style. + /// + /// The `PaintType` is not any involved in this method! fn make_styles(&self, _paint_type: Option<&PaintType>) -> String { format!("{}", self.code) } } +/// A macro for generating formatter constants. macro_rules! formatter_code { ($name:ident, $code:expr) => { pub const $name: Styles = Styles::StyleFormatter(Formatter { code: $code }); @@ -82,6 +87,7 @@ mod tests { } } + /// A macro for generating formatter tests. macro_rules! formatter_test { ($test_name:ident, $formatter_name:ident, $code:expr) => { #[test] From 217ce508770695c0f521cd7f2ebf7e3035c6eb0d Mon Sep 17 00:00:00 2001 From: syaw0 Date: Thu, 7 Nov 2024 10:24:48 +0330 Subject: [PATCH 38/51] doc(paint_type.rs): Add document for a module --- src/styles/paint_type.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/styles/paint_type.rs b/src/styles/paint_type.rs index ad680bd..10f9970 100644 --- a/src/styles/paint_type.rs +++ b/src/styles/paint_type.rs @@ -1,14 +1,30 @@ +/// A module for working with paint types. +/// +/// This module provides an enum `PaintType` that represents different types of paint. +/// It also implements the `Stylify` trait for `PaintType`, which allows for generating styles based on the paint type. + +// ======================================================================= + use super::Stylify; // ======================================================================= +/// An enum representing different types of paint. +/// +/// This enum has two variants: `FG` and `BG`, which represent foreground and background paint, respectively. #[derive(Debug, Clone)] pub enum PaintType { + /// Foreground paint. FG, + /// Background paint. BG, } impl Stylify for PaintType { + /// Generates styles based on the paint type. + /// + /// This method takes an optional `paint_type` parameter, which is ignored in this implementation. + /// It returns an empty string, indicating that no styles are generated. fn make_styles(&self, _paint_type: Option<&PaintType>) -> String { String::new() } From 8fe8c7057af5f7b2929ec90ac344454df80f0004 Mon Sep 17 00:00:00 2001 From: syaw0 Date: Thu, 7 Nov 2024 10:25:21 +0330 Subject: [PATCH 39/51] test(paint_type.rs): Add basic tests for a module --- src/styles/paint_type.rs | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/src/styles/paint_type.rs b/src/styles/paint_type.rs index 10f9970..39f29d7 100644 --- a/src/styles/paint_type.rs +++ b/src/styles/paint_type.rs @@ -29,3 +29,34 @@ impl Stylify for PaintType { String::new() } } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_make_styles() { + let paint_type = PaintType::FG; + let styles = paint_type.make_styles(None); + assert_eq!(styles, String::new()); + + let paint_type = PaintType::BG; + let styles = paint_type.make_styles(Some(&PaintType::FG)); + assert_eq!(styles, String::new()); + } + + #[test] + fn test_make_styles_null_input() { + let paint_type = PaintType::FG; + let styles = paint_type.make_styles(None); + assert_eq!(styles, String::new()); + } + + #[test] + fn test_make_styles_multiple_calls() { + let paint_type = PaintType::FG; + let styles1 = paint_type.make_styles(None); + let styles2 = paint_type.make_styles(None); + assert_eq!(styles1, styles2); + } +} From 8b9f3c84484a679a58951ea66a35bb953d46cd5d Mon Sep 17 00:00:00 2001 From: syaw0 Date: Thu, 7 Nov 2024 10:30:16 +0330 Subject: [PATCH 40/51] doc(palette.rs): Add document for a module --- src/styles/palette.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/styles/palette.rs b/src/styles/palette.rs index 1ea9fd1..e7a4db6 100644 --- a/src/styles/palette.rs +++ b/src/styles/palette.rs @@ -1,13 +1,28 @@ +/// A module for creating palette color. +/// +/// This module provides an struct `PaletteColor` +/// that represents palette color, index should be between 0 to 255 mean u8. +/// It also implements the `Stylify` trait for `PaletteColor`, +/// which allows for generating styles based on the paint type. + +// ======================================================================= + use super::{ paint_type::PaintType, Stylify }; // ======================================================================= +/// An struct representing index of palette color. +/// +/// This struct has 1 field: `index`, which represent 8 bit color code between 0 to 255. #[derive(Debug, Clone)] pub struct PaletteColor { pub index: u8, } impl Stylify for PaletteColor { + /// Returns a string representation of the palette index code. + /// + /// If `paint_type` is `None`, the foreground color is assumed. fn make_styles(&self, paint_type: Option<&PaintType>) -> String { let paint_type = paint_type.unwrap_or(&PaintType::FG); format!( From d981ce94432b90819a6d24709eabfd491395ab89 Mon Sep 17 00:00:00 2001 From: syaw0 Date: Thu, 7 Nov 2024 10:34:26 +0330 Subject: [PATCH 41/51] test(palette.rs): Add tests for a module --- src/styles/palette.rs | 44 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/src/styles/palette.rs b/src/styles/palette.rs index e7a4db6..c124519 100644 --- a/src/styles/palette.rs +++ b/src/styles/palette.rs @@ -35,3 +35,47 @@ impl Stylify for PaletteColor { ) } } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_make_style_fg() { + let color = PaletteColor { index: 42 }; + let styles = color.make_styles(Some(&PaintType::FG)); + assert_eq!(styles, "38;5;42") + } + + #[test] + fn test_make_style_default_fg() { + let color = PaletteColor { index: 105 }; + let styles = color.make_styles(None); + assert_eq!(styles, "38;5;105") + } + + #[test] + fn test_make_style_bg() { + let color = PaletteColor { index: 1 }; + let styles = color.make_styles(Some(&PaintType::BG)); + assert_eq!(styles, "48;5;1") + } + + #[test] + fn test_fg_and_bg_values() { + let color = PaletteColor { index: 200 }; + let styles_fg = color.make_styles(Some(&PaintType::FG)); + let styles_bg = color.make_styles(Some(&PaintType::BG)); + assert_eq!(styles_fg, "38;5;200"); + assert_eq!(styles_bg, "48;5;200") + } + + #[test] + fn test_fg_and_bg_values_with_none_paint_type() { + let color = PaletteColor { index: 108 }; + let styles_fg = color.make_styles(None); + let styles_bg = color.make_styles(Some(&PaintType::BG)); + assert_eq!(styles_fg, "38;5;108"); + assert_eq!(styles_bg, "48;5;108") + } +} From 745d58294d6d3b5159e76e54863bdfb9d3d83388 Mon Sep 17 00:00:00 2001 From: syaw0 Date: Thu, 7 Nov 2024 10:37:13 +0330 Subject: [PATCH 42/51] doc(rgb.rs): Add test for a module --- src/styles/rgb.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/styles/rgb.rs b/src/styles/rgb.rs index f871407..f756ca5 100644 --- a/src/styles/rgb.rs +++ b/src/styles/rgb.rs @@ -1,7 +1,19 @@ +/// A module for creating rgb color. +/// +/// This module provides an struct `Rgb` +/// that represents rgb color, with r,g,b field. +/// It also implements the `Stylify` trait for `Rgb`, +/// which allows for generating styles based on the paint type. + +// ======================================================================= + use super::{ paint_type::PaintType, Stylify }; // ======================================================================= +/// An struct representing rgb color. +/// +/// This struct has 3 field: `r`, `g` and `b` , which each of them represent 8 bit color code between 0 to 255. #[derive(Debug, Clone)] pub struct Rgb { pub r: u8, @@ -10,6 +22,9 @@ pub struct Rgb { } impl Stylify for Rgb { + /// Returns a string representation of the rgb color code. + /// + /// If `paint_type` is `None`, the foreground color is assumed. fn make_styles(&self, paint_type: Option<&PaintType>) -> String { let paint_type = paint_type.unwrap_or(&PaintType::FG); format!( From fadfff3c763b7cae4dcf71ae57d0ae766e2f8371 Mon Sep 17 00:00:00 2001 From: syaw0 Date: Thu, 7 Nov 2024 10:40:31 +0330 Subject: [PATCH 43/51] test(rgb.rs): Add tests for a module --- src/styles/rgb.rs | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/src/styles/rgb.rs b/src/styles/rgb.rs index f756ca5..f8a6b3b 100644 --- a/src/styles/rgb.rs +++ b/src/styles/rgb.rs @@ -39,3 +39,47 @@ impl Stylify for Rgb { ) } } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_make_style_fg() { + let color = Rgb { r: 102, g: 23, b: 240 }; + let styles = color.make_styles(Some(&PaintType::FG)); + assert_eq!(styles, "38;2;102;23;240") + } + + #[test] + fn test_make_style_default_fg() { + let color = Rgb { r: 2, g: 55, b: 100 }; + let styles = color.make_styles(None); + assert_eq!(styles, "38;2;2;55;100") + } + + #[test] + fn test_make_style_bg() { + let color = Rgb { r: 255, g: 255, b: 43 }; + let styles = color.make_styles(Some(&PaintType::BG)); + assert_eq!(styles, "48;2;255;255;43") + } + + #[test] + fn test_fg_and_bg_values() { + let color = Rgb { r: 78, g: 32, b: 210 }; + let styles_fg = color.make_styles(Some(&PaintType::FG)); + let styles_bg = color.make_styles(Some(&PaintType::BG)); + assert_eq!(styles_fg, "38;2;78;32;210"); + assert_eq!(styles_bg, "48;2;78;32;210") + } + + #[test] + fn test_fg_and_bg_values_with_none_paint_type() { + let color = Rgb { r: 1, g: 91, b: 58 }; + let styles_fg = color.make_styles(None); + let styles_bg = color.make_styles(Some(&PaintType::BG)); + assert_eq!(styles_fg, "38;2;1;91;58"); + assert_eq!(styles_bg, "48;2;1;91;58") + } +} From 1302bcd53ed67ecd2f14c03d726465d587d636fc Mon Sep 17 00:00:00 2001 From: syaw0 Date: Thu, 7 Nov 2024 10:44:31 +0330 Subject: [PATCH 44/51] doc(ansi_code.rs): add basic document for a module --- src/ansi_code.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/ansi_code.rs b/src/ansi_code.rs index bb1fea8..27fdef4 100644 --- a/src/ansi_code.rs +++ b/src/ansi_code.rs @@ -1,11 +1,25 @@ +/// A module for creating ansi escape code. +/// +/// This module provides an struct `ANSIEscapeCode` +/// that represents ansi escape code, with `parameter` field. +/// It also implements the `ANSIEscapeCode`, with `new` and `code` method +/// which allows for generating anis escape code and getting a code. + +// ======================================================================= + +/// An struct representing ansi escape code. +/// +/// This struct has 1 field: `parameter` , which represent String of the ansi code. pub struct ANSIEscapeCode { parameter: String, } impl ANSIEscapeCode { + /// Returns a ANSIEscapeCode instance with parameter . pub fn new(parameter: &str) -> Self { ANSIEscapeCode { parameter: parameter.to_string() } } + /// Returns a String that represent the ansi code. pub fn code(&self) -> String { format!("\x1b[{}m", self.parameter) } From f5bb741807b1645a91be5e39fee901f318ee9bcf Mon Sep 17 00:00:00 2001 From: syaw0 Date: Thu, 7 Nov 2024 10:48:48 +0330 Subject: [PATCH 45/51] doc(styles.rs): Add basic document for a module --- src/styles.rs | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/src/styles.rs b/src/styles.rs index 9f8f29d..c4480f7 100644 --- a/src/styles.rs +++ b/src/styles.rs @@ -1,3 +1,11 @@ +/// A module for working with styles and colors. +/// +/// This module provides a set of types and traits for representing +/// different styles and colors, +/// as well as a way to generate styles based on a given paint type. + +// ======================================================================= + use basic_color::BasicColor; use formatter::Formatter; use paint_type::PaintType; @@ -5,7 +13,6 @@ use palette::PaletteColor; use rgb::Rgb; // ======================================================================= - pub mod paint_type; pub mod formatter; pub mod basic_color; @@ -14,16 +21,37 @@ pub mod palette; // ======================================================================= +/// An enum representing different styles. +/// +/// This enum has five variants, each representing a different type of style: +/// `StyleRgb`, `StyleBasicColor`, `StylePaletteColor`, `StylePaintType`, and `StyleFormatter`. +/// +/// # Examples +/// +/// ``` +/// let style = Styles::StyleRgb(Rgb::new(255, 0, 0)); +/// let paint_type = PaintType::FG; +/// let styles = style.make_styles(Some(&paint_type)); +/// ``` #[derive(Debug, Clone)] pub enum Styles { + /// A style represented by an RGB color. StyleRgb(Rgb), + /// A style represented by a basic color. StyleBasicColor(BasicColor), + /// A style represented by a palette color. StylePaletteColor(PaletteColor), + /// A style represented by a paint type. StylePaintType(PaintType), + /// A style represented by a formatter. StyleFormatter(Formatter), } impl Styles { + /// Generates String styles based on the given paint type. + /// + /// This method takes an optional `paint_type` parameter, which is used to determine the styles to generate. + /// It returns a string representing the generated styles. pub fn make_styles(&self, paint_type: Option<&PaintType>) -> String { match self { Styles::StyleBasicColor(c) => c.make_styles(paint_type), @@ -35,6 +63,11 @@ impl Styles { } } +/// A trait for types that can generate styles based on a given paint type. pub trait Stylify { + /// Generates String styles based on the given paint type. + /// + /// This method takes an optional `paint_type` parameter, which is used to determine the styles to generate. + /// It returns a string representing the generated styles. fn make_styles(&self, paint_type: Option<&PaintType>) -> String; } From 1a679846e92e834eaefb57bee688b2c42dd49cb4 Mon Sep 17 00:00:00 2001 From: syaw0 Date: Thu, 7 Nov 2024 10:58:10 +0330 Subject: [PATCH 46/51] feat: Public the field of BasicColor and Formatter struct --- src/styles/basic_color.rs | 4 ++-- src/styles/formatter.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/styles/basic_color.rs b/src/styles/basic_color.rs index 707a894..7e7fc34 100644 --- a/src/styles/basic_color.rs +++ b/src/styles/basic_color.rs @@ -6,9 +6,9 @@ use super::{ paint_type::PaintType, Styles, Stylify }; #[derive(Debug, Clone)] pub struct BasicColor { /// The foreground color value. - fg: u8, + pub fg: u8, /// The background color value. - bg: u8, + pub bg: u8, } impl Stylify for BasicColor { diff --git a/src/styles/formatter.rs b/src/styles/formatter.rs index 13ffd07..07ded3d 100644 --- a/src/styles/formatter.rs +++ b/src/styles/formatter.rs @@ -5,7 +5,7 @@ use super::{ paint_type::PaintType, Styles, Stylify }; /// A struct representing a Formatter with code value. #[derive(Debug, Clone)] pub struct Formatter { - code: u8, + pub code: u8, } impl Stylify for Formatter { From 6fbd3b541efbd3aa5b13a32690fa23313b08e7f0 Mon Sep 17 00:00:00 2001 From: syaw0 Date: Thu, 7 Nov 2024 10:58:39 +0330 Subject: [PATCH 47/51] test(styles.rs): Add tests for a module --- src/styles.rs | 60 ++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 52 insertions(+), 8 deletions(-) diff --git a/src/styles.rs b/src/styles.rs index c4480f7..955349f 100644 --- a/src/styles.rs +++ b/src/styles.rs @@ -25,14 +25,6 @@ pub mod palette; /// /// This enum has five variants, each representing a different type of style: /// `StyleRgb`, `StyleBasicColor`, `StylePaletteColor`, `StylePaintType`, and `StyleFormatter`. -/// -/// # Examples -/// -/// ``` -/// let style = Styles::StyleRgb(Rgb::new(255, 0, 0)); -/// let paint_type = PaintType::FG; -/// let styles = style.make_styles(Some(&paint_type)); -/// ``` #[derive(Debug, Clone)] pub enum Styles { /// A style represented by an RGB color. @@ -71,3 +63,55 @@ pub trait Stylify { /// It returns a string representing the generated styles. fn make_styles(&self, paint_type: Option<&PaintType>) -> String; } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_make_styles() { + let style = Styles::StyleRgb(Rgb { r: 255, g: 0, b: 0 }); + let styles_default = style.make_styles(None); + let styles_fg = style.make_styles(Some(&PaintType::FG)); + let styles_bg = style.make_styles(Some(&PaintType::BG)); + assert_eq!(styles_default, "38;2;255;0;0"); + assert_eq!(styles_fg, "38;2;255;0;0"); + assert_eq!(styles_bg, "48;2;255;0;0"); + + // + let style = Styles::StyleBasicColor(BasicColor { fg: 34, bg: 44 }); + let styles_default = style.make_styles(None); + let styles_fg = style.make_styles(Some(&PaintType::FG)); + let styles_bg = style.make_styles(Some(&PaintType::BG)); + assert_eq!(styles_default, "34"); + assert_eq!(styles_fg, "34"); + assert_eq!(styles_bg, "44"); + + // + let style = Styles::StylePaletteColor(PaletteColor { index: 44 }); + let styles_default = style.make_styles(None); + let styles_fg = style.make_styles(Some(&PaintType::FG)); + let styles_bg = style.make_styles(Some(&PaintType::BG)); + assert_eq!(styles_default, "38;5;44"); + assert_eq!(styles_fg, "38;5;44"); + assert_eq!(styles_bg, "48;5;44"); + + // + let style = Styles::StylePaintType(PaintType::BG); + let styles_default = style.make_styles(None); + let styles_fg = style.make_styles(Some(&PaintType::FG)); + let styles_bg = style.make_styles(Some(&PaintType::BG)); + assert_eq!(styles_default, ""); + assert_eq!(styles_fg, ""); + assert_eq!(styles_bg, ""); + + // + let style = Styles::StyleFormatter(Formatter { code: 3 }); + let styles_default = style.make_styles(None); + let styles_fg = style.make_styles(Some(&PaintType::FG)); + let styles_bg = style.make_styles(Some(&PaintType::BG)); + assert_eq!(styles_default, "3"); + assert_eq!(styles_fg, "3"); + assert_eq!(styles_bg, "3"); + } +} From f57bbf452bfb2812ef57d95a20fd9876c0b59a4c Mon Sep 17 00:00:00 2001 From: syaw0 Date: Thu, 7 Nov 2024 11:28:04 +0330 Subject: [PATCH 48/51] doc(lib.rs): Add document for a public api --- src/lib.rs | 228 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 223 insertions(+), 5 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index fdd1d1f..9e617db 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,6 +1,7 @@ -//! # Vitalux: Rich Api For Colorize Terminal -//! +//! # Vitalux: Rich API for Colorizing Terminal //! +//! Vitalux is a Rust library that provides a rich API for colorizing terminal output. +//! It allows you to create styled text strings with various colors, effects, and formatters. mod ansi_code; mod styles; @@ -35,7 +36,7 @@ use crate::{ /// .italic() /// .rapid_blink() /// .bg() -/// .rgb(74, 56, 7) +/// .black() /// .fg() /// .paint(); /// println!("{txt}"); @@ -50,6 +51,7 @@ use crate::{ /// * `rapid_blink()`: Sets the text to rapidly blink. /// * `bg()`: Sets the background color. /// * `fg()`: Sets the foreground color. +/// * basic colors like : `red`,`black` and etc. /// /// # Colors /// @@ -70,21 +72,24 @@ pub fn styled(text: &str) -> StyledText { StyledText::new(text.to_string()) } +/// A struct representing a styled text string. pub struct StyledText { text: String, start_styles: Vec, } impl StyledText { + /// Creates a new `StyledText` object with the given text. fn new(text: String) -> Self { - // we should use Formatter::reset() - // let reset_ansi = ANSIEscapeCode::new("0"); StyledText { text, start_styles: vec![], } } + /// Paints the styled text string with the given styles. + /// + /// This method returns a string representing the styled text. pub fn paint(&mut self) -> String { let mut default_paint_type = PaintType::FG; @@ -111,11 +116,33 @@ impl StyledText { format!("{}{}{}", start_codes, self.text, end_codes) } + /// Sets the foreground color of the colors you have called. + /// + /// # Example: + /// ``` + /// use vitalux::styled; + /// let styled_text = styled("How you doing?").black().fg().red().bg().paint(); + /// ``` + /// the colors before this method will paint as foreground! + /// so the black color will paint as foreground and red color paint + /// as background color + /// **if the one `fg` call, all the colors will paint as foreground no matter there is before or after `fg`** pub fn fg(&mut self) -> &mut Self { self.start_styles.push(Styles::StylePaintType(PaintType::FG)); self } + /// Sets the background color of the colors you have called. + /// + /// # Example: + /// ``` + /// use vitalux::styled; + /// let styled_text = styled("I'm feel Happy").bright_cyan().bg().blue().fg().paint(); + /// ``` + /// the colors before this method will paint as background! + /// so the bright_cyan color will paint as background and blue color paint + /// as foreground color + /// **if the one `bg` call, all the colors will paint as background no matter there is before or after `bg`** pub fn bg(&mut self) -> &mut Self { self.start_styles.push(Styles::StylePaintType(PaintType::BG)); self @@ -123,91 +150,220 @@ impl StyledText { // Colors + /// Sets the `rgb` color to the input text. + /// + /// # Example: + /// ``` + /// use vitalux::styled; + /// let styled_text = styled("Our life is what our thoughts make it.").rgb(48,118,230).paint(); + /// ``` pub fn rgb(&mut self, r: u8, g: u8, b: u8) -> &mut Self { self.start_styles.push(Styles::StyleRgb(Rgb { r, g, b })); self } + /// Sets the `palette` color to the input text. + /// + /// # Example: + /// ``` + /// use vitalux::styled; + /// let styled_text = styled("If it is not right, do not do it. If it is not true, do not say it.").palette(132).paint(); + /// ``` + /// + /// the index should be 8 bit color between 0 to 255. pub fn palette(&mut self, index: u8) -> &mut Self { self.start_styles.push(Styles::StylePaletteColor(PaletteColor { index })); self } + /// Sets the `black` color to the input text. + /// + /// # Example: + /// ``` + /// use vitalux::styled; + /// let styled_text = styled("The best revenge is to not be like your enemies.").black().paint(); + /// ``` pub fn black(&mut self) -> &mut Self { self.start_styles.push(basic_color::BLACK); self } + /// Sets the `red` color to the input text. + /// + /// # Example: + /// ``` + /// use vitalux::styled; + /// let styled_text = styled("To love only what happens, what was destined. No greater harmony.").red().paint(); + /// ``` pub fn red(&mut self) -> &mut Self { self.start_styles.push(basic_color::RED); self } + /// Sets the `green` color to the input text. + /// + /// # Example: + /// ``` + /// use vitalux::styled; + /// let styled_text = styled("Everything we hear is opinion, not a fact. Everything we see is a perspective, not the truth.").green().paint(); + /// ``` pub fn green(&mut self) -> &mut Self { self.start_styles.push(basic_color::GREEN); self } + /// Sets the `yellow` color to the input text. + /// + /// # Example: + /// ``` + /// use vitalux::styled; + /// let styled_text = styled("The present is all we have to live in . . . or to lose.").yellow().paint(); + /// ``` pub fn yellow(&mut self) -> &mut Self { self.start_styles.push(basic_color::YELLOW); self } + /// Sets the `blue` color to the input text. + /// + /// # Example: + /// ``` + /// use vitalux::styled; + /// let styled_text = styled("The present is all we have to live in . . . or to lose.").blue().paint(); + /// ``` pub fn blue(&mut self) -> &mut Self { self.start_styles.push(basic_color::BLUE); self } + /// Sets the `magenta` color to the input text. + /// + /// # Example: + /// ``` + /// use vitalux::styled; + /// let styled_text = styled("The present is all we have to live in . . . or to lose.").magenta().paint(); + /// ``` pub fn magenta(&mut self) -> &mut Self { self.start_styles.push(basic_color::MAGENTA); self } + /// Sets the `cyan` color to the input text. + /// + /// # Example: + /// ``` + /// use vitalux::styled; + /// let styled_text = styled("The present is all we have to live in . . . or to lose.").cyan().paint(); + /// ``` pub fn cyan(&mut self) -> &mut Self { self.start_styles.push(basic_color::CYAN); self } + /// Sets the `white` color to the input text. + /// + /// # Example: + /// ``` + /// use vitalux::styled; + /// let styled_text = styled("The present is all we have to live in . . . or to lose.").white().paint(); + /// ``` pub fn white(&mut self) -> &mut Self { self.start_styles.push(basic_color::WHITE); self } + /// Sets the `gray` color to the input text. + /// + /// # Example: + /// ``` + /// use vitalux::styled; + /// let styled_text = styled("The present is all we have to live in . . . or to lose.").gray().paint(); + /// ``` pub fn gray(&mut self) -> &mut Self { self.start_styles.push(basic_color::GRAY); self } + /// Sets the `bright_red` color to the input text. + /// + /// # Example: + /// ``` + /// use vitalux::styled; + /// let styled_text = styled("The present is all we have to live in . . . or to lose.").bright_red().paint(); + /// ``` pub fn bright_red(&mut self) -> &mut Self { self.start_styles.push(basic_color::BRIGHT_RED); self } + /// Sets the `bright_green` color to the input text. + /// + /// # Example: + /// ``` + /// use vitalux::styled; + /// let styled_text = styled("The present is all we have to live in . . . or to lose.").bright_green().paint(); + /// ``` pub fn bright_green(&mut self) -> &mut Self { self.start_styles.push(basic_color::BRIGHT_GREEN); self } + /// Sets the `bright_yellow` color to the input text. + /// + /// # Example: + /// ``` + /// use vitalux::styled; + /// let styled_text = styled("The present is all we have to live in . . . or to lose.").bright_yellow().paint(); + /// ``` pub fn bright_yellow(&mut self) -> &mut Self { self.start_styles.push(basic_color::BRIGHT_YELLOW); self } + /// Sets the `bright_blue` color to the input text. + /// + /// # Example: + /// ``` + /// use vitalux::styled; + /// let styled_text = styled("The present is all we have to live in . . . or to lose.").bright_blue().paint(); + /// ``` pub fn bright_blue(&mut self) -> &mut Self { self.start_styles.push(basic_color::BRIGHT_BLUE); self } + /// Sets the `bright_magenta` color to the input text. + /// + /// # Example: + /// ``` + /// use vitalux::styled; + /// let styled_text = styled("The present is all we have to live in . . . or to lose.").bright_magenta().paint(); + /// ``` + /// use vitalux::styled; pub fn bright_magenta(&mut self) -> &mut Self { self.start_styles.push(basic_color::BRIGHT_MAGENTA); self } + /// Sets the `bright_cyan` color to the input text. + /// + /// # Example: + /// ``` + /// use vitalux::styled; + /// let styled_text = styled("The present is all we have to live in . . . or to lose.").bright_cyan().paint(); + /// ``` pub fn bright_cyan(&mut self) -> &mut Self { self.start_styles.push(basic_color::BRIGHT_CYAN); self } + /// Sets the `bright_white` color to the input text. + /// + /// # Example: + /// ``` + /// use vitalux::styled; + /// let styled_text = styled("The present is all we have to live in . . . or to lose.").bright_white().paint(); + /// ``` pub fn bright_white(&mut self) -> &mut Self { self.start_styles.push(basic_color::BRIGHT_WHITE); self @@ -215,41 +371,103 @@ impl StyledText { // Formatters + /// Sets the `reset` effect to the input text. + /// + /// # Example: + /// ``` + /// use vitalux::styled; + /// let styled_text = styled("The present is all we have to live in . . . or to lose.").red().reset().paint(); + /// ``` + /// ** this will reset all the effects, colors and formatters that are called before this** + /// so in the top example the red color will never applied to the input text pub fn reset(&mut self) -> &mut Self { self.start_styles.push(formatter::RESET); self } + /// Sets the `bold` format to the input text. + /// + /// # Example: + /// ``` + /// use vitalux::styled; + /// let styled_text = styled("The present is all we have to live in . . . or to lose.").bold().paint(); + /// ``` pub fn bold(&mut self) -> &mut Self { self.start_styles.push(formatter::BOLD); self } + /// Sets the `faint` format to the input text. + /// + /// # Example: + /// ``` + /// use vitalux::styled; + /// let styled_text = styled("The present is all we have to live in . . . or to lose.").faint().paint(); + /// ``` pub fn faint(&mut self) -> &mut Self { self.start_styles.push(formatter::FAINT); self } + /// Sets the `italic` format to the input text. + /// + /// # Example: + /// ``` + /// use vitalux::styled; + /// let styled_text = styled("The present is all we have to live in . . . or to lose.").italic().paint(); + /// ``` pub fn italic(&mut self) -> &mut Self { self.start_styles.push(formatter::ITALIC); self } + /// Sets the `underline` format to the input text. + /// + /// # Example: + /// ``` + /// use vitalux::styled; + /// let styled_text = styled("The present is all we have to live in . . . or to lose.").underline().paint(); + /// ``` pub fn underline(&mut self) -> &mut Self { self.start_styles.push(formatter::UNDERLINE); self } + /// Sets the `slow_blink` effect to the input text. + /// + /// # Example: + /// ``` + /// use vitalux::styled; + /// let styled_text = styled("The present is all we have to live in . . . or to lose.").slow_blink().paint(); + /// ``` + /// + /// **base on the terminal you are using this could not be applied** pub fn slow_blink(&mut self) -> &mut Self { self.start_styles.push(formatter::SLOW_BLINK); self } + /// Sets the `rapid_blink` effect to the input text. + /// + /// # Example: + /// ``` + /// use vitalux::styled; + /// let styled_text = styled("The present is all we have to live in . . . or to lose.").rapid_blink().paint(); + /// ``` + /// + /// **base on the terminal you are using this could not be applied** pub fn rapid_blink(&mut self) -> &mut Self { self.start_styles.push(formatter::RAPID_BLINK); self } + /// Sets the `overline` effect to the input text. + /// + /// # Example: + /// ``` + /// use vitalux::styled; + /// let styled_text = styled("The present is all we have to live in . . . or to lose.").overline().paint(); + /// ``` pub fn overline(&mut self) -> &mut Self { self.start_styles.push(formatter::OVERLINE); self From 01bfd96885371df012cbc3c477e8fcf410dd8df8 Mon Sep 17 00:00:00 2001 From: syaw0 Date: Sat, 9 Nov 2024 18:18:14 +0330 Subject: [PATCH 49/51] chore: rename a package to `term_tools` --- Cargo.lock | 2 +- Cargo.toml | 10 ++++----- src/lib.rs | 64 ++++++++++++++++++++++++++--------------------------- src/main.rs | 3 --- 4 files changed, 38 insertions(+), 41 deletions(-) delete mode 100644 src/main.rs diff --git a/Cargo.lock b/Cargo.lock index 7404c03..496b64a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3,5 +3,5 @@ version = 3 [[package]] -name = "vitalux" +name = "term_tools" version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml index 2b66608..f291f2c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,13 +1,13 @@ [package] -name = "vitalux" +name = "term_tools" version = "0.1.0" edition = "2021" -description = "Colorize Your Terminal with Vitalux: A Rust-powered Formatting Tool" +description = "Colorize Your Terminal with Term-Tools: A Rust-powered Formatting Tool" authors = ["Siavash Siamhb7@protonmail.com"] -homepage = "https://crates.io/crates/vitalux" -repository = "https://github.com/Syaw0/Vitalux" +homepage = "https://crates.io/crates/term_tools" +repository = "https://github.com/Syaw0/term_tools" license-file = "./LICENSE" keywords = ["cli","terminal","rust","tool","coloize","formatter"] -categories = ["terminal","cli","command-line-utilitise"] +categories = ["terminal","cli","command-line-utilitise","term-style", "terminal style"] [dependencies] diff --git a/src/lib.rs b/src/lib.rs index 9e617db..d5914c5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,6 +1,6 @@ -//! # Vitalux: Rich API for Colorizing Terminal +//! # Term_Tools: Rich API for Colorizing Terminal //! -//! Vitalux is a Rust library that provides a rich API for colorizing terminal output. +//! term_tools is a Rust library that provides a rich API for colorizing terminal output. //! It allows you to create styled text strings with various colors, effects, and formatters. mod ansi_code; @@ -29,7 +29,7 @@ use crate::{ /// # Examples /// /// ``` -/// use vitalux::styled; +/// use term_tools::styled; /// /// let txt = styled("Happy Day!") /// .rgb(204, 182, 122) @@ -120,7 +120,7 @@ impl StyledText { /// /// # Example: /// ``` - /// use vitalux::styled; + /// use term_tools::styled; /// let styled_text = styled("How you doing?").black().fg().red().bg().paint(); /// ``` /// the colors before this method will paint as foreground! @@ -136,7 +136,7 @@ impl StyledText { /// /// # Example: /// ``` - /// use vitalux::styled; + /// use term_tools::styled; /// let styled_text = styled("I'm feel Happy").bright_cyan().bg().blue().fg().paint(); /// ``` /// the colors before this method will paint as background! @@ -154,7 +154,7 @@ impl StyledText { /// /// # Example: /// ``` - /// use vitalux::styled; + /// use term_tools::styled; /// let styled_text = styled("Our life is what our thoughts make it.").rgb(48,118,230).paint(); /// ``` pub fn rgb(&mut self, r: u8, g: u8, b: u8) -> &mut Self { @@ -166,7 +166,7 @@ impl StyledText { /// /// # Example: /// ``` - /// use vitalux::styled; + /// use term_tools::styled; /// let styled_text = styled("If it is not right, do not do it. If it is not true, do not say it.").palette(132).paint(); /// ``` /// @@ -180,7 +180,7 @@ impl StyledText { /// /// # Example: /// ``` - /// use vitalux::styled; + /// use term_tools::styled; /// let styled_text = styled("The best revenge is to not be like your enemies.").black().paint(); /// ``` pub fn black(&mut self) -> &mut Self { @@ -192,7 +192,7 @@ impl StyledText { /// /// # Example: /// ``` - /// use vitalux::styled; + /// use term_tools::styled; /// let styled_text = styled("To love only what happens, what was destined. No greater harmony.").red().paint(); /// ``` pub fn red(&mut self) -> &mut Self { @@ -204,7 +204,7 @@ impl StyledText { /// /// # Example: /// ``` - /// use vitalux::styled; + /// use term_tools::styled; /// let styled_text = styled("Everything we hear is opinion, not a fact. Everything we see is a perspective, not the truth.").green().paint(); /// ``` pub fn green(&mut self) -> &mut Self { @@ -216,7 +216,7 @@ impl StyledText { /// /// # Example: /// ``` - /// use vitalux::styled; + /// use term_tools::styled; /// let styled_text = styled("The present is all we have to live in . . . or to lose.").yellow().paint(); /// ``` pub fn yellow(&mut self) -> &mut Self { @@ -228,7 +228,7 @@ impl StyledText { /// /// # Example: /// ``` - /// use vitalux::styled; + /// use term_tools::styled; /// let styled_text = styled("The present is all we have to live in . . . or to lose.").blue().paint(); /// ``` pub fn blue(&mut self) -> &mut Self { @@ -240,7 +240,7 @@ impl StyledText { /// /// # Example: /// ``` - /// use vitalux::styled; + /// use term_tools::styled; /// let styled_text = styled("The present is all we have to live in . . . or to lose.").magenta().paint(); /// ``` pub fn magenta(&mut self) -> &mut Self { @@ -252,7 +252,7 @@ impl StyledText { /// /// # Example: /// ``` - /// use vitalux::styled; + /// use term_tools::styled; /// let styled_text = styled("The present is all we have to live in . . . or to lose.").cyan().paint(); /// ``` pub fn cyan(&mut self) -> &mut Self { @@ -264,7 +264,7 @@ impl StyledText { /// /// # Example: /// ``` - /// use vitalux::styled; + /// use term_tools::styled; /// let styled_text = styled("The present is all we have to live in . . . or to lose.").white().paint(); /// ``` pub fn white(&mut self) -> &mut Self { @@ -276,7 +276,7 @@ impl StyledText { /// /// # Example: /// ``` - /// use vitalux::styled; + /// use term_tools::styled; /// let styled_text = styled("The present is all we have to live in . . . or to lose.").gray().paint(); /// ``` pub fn gray(&mut self) -> &mut Self { @@ -288,7 +288,7 @@ impl StyledText { /// /// # Example: /// ``` - /// use vitalux::styled; + /// use term_tools::styled; /// let styled_text = styled("The present is all we have to live in . . . or to lose.").bright_red().paint(); /// ``` pub fn bright_red(&mut self) -> &mut Self { @@ -300,7 +300,7 @@ impl StyledText { /// /// # Example: /// ``` - /// use vitalux::styled; + /// use term_tools::styled; /// let styled_text = styled("The present is all we have to live in . . . or to lose.").bright_green().paint(); /// ``` pub fn bright_green(&mut self) -> &mut Self { @@ -312,7 +312,7 @@ impl StyledText { /// /// # Example: /// ``` - /// use vitalux::styled; + /// use term_tools::styled; /// let styled_text = styled("The present is all we have to live in . . . or to lose.").bright_yellow().paint(); /// ``` pub fn bright_yellow(&mut self) -> &mut Self { @@ -324,7 +324,7 @@ impl StyledText { /// /// # Example: /// ``` - /// use vitalux::styled; + /// use term_tools::styled; /// let styled_text = styled("The present is all we have to live in . . . or to lose.").bright_blue().paint(); /// ``` pub fn bright_blue(&mut self) -> &mut Self { @@ -336,10 +336,10 @@ impl StyledText { /// /// # Example: /// ``` - /// use vitalux::styled; + /// use term_tools::styled; /// let styled_text = styled("The present is all we have to live in . . . or to lose.").bright_magenta().paint(); /// ``` - /// use vitalux::styled; + /// use term_tools::styled; pub fn bright_magenta(&mut self) -> &mut Self { self.start_styles.push(basic_color::BRIGHT_MAGENTA); self @@ -349,7 +349,7 @@ impl StyledText { /// /// # Example: /// ``` - /// use vitalux::styled; + /// use term_tools::styled; /// let styled_text = styled("The present is all we have to live in . . . or to lose.").bright_cyan().paint(); /// ``` pub fn bright_cyan(&mut self) -> &mut Self { @@ -361,7 +361,7 @@ impl StyledText { /// /// # Example: /// ``` - /// use vitalux::styled; + /// use term_tools::styled; /// let styled_text = styled("The present is all we have to live in . . . or to lose.").bright_white().paint(); /// ``` pub fn bright_white(&mut self) -> &mut Self { @@ -375,7 +375,7 @@ impl StyledText { /// /// # Example: /// ``` - /// use vitalux::styled; + /// use term_tools::styled; /// let styled_text = styled("The present is all we have to live in . . . or to lose.").red().reset().paint(); /// ``` /// ** this will reset all the effects, colors and formatters that are called before this** @@ -389,7 +389,7 @@ impl StyledText { /// /// # Example: /// ``` - /// use vitalux::styled; + /// use term_tools::styled; /// let styled_text = styled("The present is all we have to live in . . . or to lose.").bold().paint(); /// ``` pub fn bold(&mut self) -> &mut Self { @@ -401,7 +401,7 @@ impl StyledText { /// /// # Example: /// ``` - /// use vitalux::styled; + /// use term_tools::styled; /// let styled_text = styled("The present is all we have to live in . . . or to lose.").faint().paint(); /// ``` pub fn faint(&mut self) -> &mut Self { @@ -413,7 +413,7 @@ impl StyledText { /// /// # Example: /// ``` - /// use vitalux::styled; + /// use term_tools::styled; /// let styled_text = styled("The present is all we have to live in . . . or to lose.").italic().paint(); /// ``` pub fn italic(&mut self) -> &mut Self { @@ -425,7 +425,7 @@ impl StyledText { /// /// # Example: /// ``` - /// use vitalux::styled; + /// use term_tools::styled; /// let styled_text = styled("The present is all we have to live in . . . or to lose.").underline().paint(); /// ``` pub fn underline(&mut self) -> &mut Self { @@ -437,7 +437,7 @@ impl StyledText { /// /// # Example: /// ``` - /// use vitalux::styled; + /// use term_tools::styled; /// let styled_text = styled("The present is all we have to live in . . . or to lose.").slow_blink().paint(); /// ``` /// @@ -451,7 +451,7 @@ impl StyledText { /// /// # Example: /// ``` - /// use vitalux::styled; + /// use term_tools::styled; /// let styled_text = styled("The present is all we have to live in . . . or to lose.").rapid_blink().paint(); /// ``` /// @@ -465,7 +465,7 @@ impl StyledText { /// /// # Example: /// ``` - /// use vitalux::styled; + /// use term_tools::styled; /// let styled_text = styled("The present is all we have to live in . . . or to lose.").overline().paint(); /// ``` pub fn overline(&mut self) -> &mut Self { diff --git a/src/main.rs b/src/main.rs deleted file mode 100644 index 6965c96..0000000 --- a/src/main.rs +++ /dev/null @@ -1,3 +0,0 @@ -fn main() { - println!("Hello I'm Vitalux!") -} From e8a2e648368a517b1847f40db95e1fce12034556 Mon Sep 17 00:00:00 2001 From: syaw0 Date: Sat, 9 Nov 2024 18:21:26 +0330 Subject: [PATCH 50/51] doc(readme.md): just change the package name inside the file --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 8989708..48e5479 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,3 @@ -# Vitalux -Colorize Your Terminal with Vitalux: A Rust-powered Formatting Tool +# Term_Tools + +Colorize Your Terminal with Term_Tools: A Rust-powered Formatting Tool From 8b40d109e6da21651ed02677fa1fab184f0c72a9 Mon Sep 17 00:00:00 2001 From: syaw0 Date: Tue, 12 Nov 2024 09:58:57 +0330 Subject: [PATCH 51/51] doc: Add a document for a package --- README.md | 136 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 134 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 48e5479..7304717 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,135 @@ -# Term_Tools +# **term_tools: Rich API for Colorizing Terminal** -Colorize Your Terminal with Term_Tools: A Rust-powered Formatting Tool +[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![Version](https://img.shields.io/badge/dynamic/toml?url=https%3A%2F%2Fraw.githubusercontent.com%2FSyaw0%2Fterm_tools%2Frefs%2Fheads%2Fdevelop%2FCargo.toml&query=package.version&label=Version&color=red)](https://crates.io/term_tools) + +## **Overview** + +term_tools is a Rust library that provides a rich API for colorizing terminal output. It allows you to create styled text strings with various colors, effects, and formatters. + +## **Features** + +- **Colors**: Supports 16 basic colors, 256 palette colors, and RGB colors. +- **Effects**: Supports slow blink and rapid blink. +- **Formatters**: Supports reset, bold, faint, italic, underline, and overline formatters. +- **Easy to use**: Simple and intuitive API for creating styled text strings. + +## **Usage** + +To use term_tools, simply add the following line to your `Cargo.toml` file: + +```toml +[dependencies] +term_tools = "0.1.0" +``` + +Then, import the library in your Rust code: + +```rust +use term_tools::styled; +``` + +Create a styled text string using the `styled` function: + +```rust +let styled_text = styled("Hello, World!") + .red() + .bold() + .underline() + .paint(); +println!("{}", styled_text); +``` + +## **Sequence of Styles** + +The sequence of styles is important when using the `fg` and `bg` methods. These methods set the foreground and background colors, respectively, for all subsequent styles. + +When you call `fg` or `bg`, all styles that come before it will be applied to the foreground or background, respectively. + +Here's an example: + +```rust +let styled_text = styled("Hello, World!") + .red() // applies to foreground + .fg() // sets foreground color to red + .blue() // applies to background + .bg() // sets background color to blue + .paint(); +``` + +In this example, the `red` style is applied to the foreground, and the `blue` style is applied to the background. + +if there is only one call of `fg` or `bg` whole colors applied that `PaintType` for example: + +```rust +let styled_text = styled("Hello, World!") + .red() // red color + .blue() // blue color + .bg() // apply background color + .magenta() // magenta color + .paint(); +``` + +in this example `paint` method will apply the background color of all colors. + +if there is not any `fg` or `bg` call , the default paint type assume as `Foreground` for example: + +```rust +let styled_text = styled("Hello, World!") + .red() // red color + .blue() // blue color + .paint(); +``` + +in this example the `paint` method will use foreground color of the colors. + +## **Examples** + +Here are some examples of using term_tools: + +- **Basic colors**: + +```rust +let styled_text = styled("Hello, World!") + .red() + .paint(); +println!("{}", styled_text); +``` + +- **RGB colors**: + +```rust +let styled_text = styled("Hello, World!") + .rgb(255, 0, 0) + .paint(); +println!("{}", styled_text); +``` + +- **Effects**: + +```rust +let styled_text = styled("Hello, World!") + .bold() + .underline() + .paint(); +println!("{}", styled_text); +``` + +- **Formatters**: + +```rust +let styled_text = styled("Hello, World!") + .reset() + .bold() + .paint(); +println!("{}", styled_text); +``` + +## **License** + +term_tools is licensed under the MIT License. + +## **Contributing** + +Contributions are welcome If you'd like to contribute to term_tools, please fork the repository and submit a pull request. + +I hope this helps Let me know if you'd like me to make any changes.