From 504d4d49bfb2b6456a71fa85216e7d2f5c7405e3 Mon Sep 17 00:00:00 2001 From: Nazmul Idris Date: Sat, 14 Dec 2024 15:00:59 -0600 Subject: [PATCH] [core][cmdr] Update lolcat api to accept a TuiStyle --- CHANGELOG.md | 156 +++-------------- cmdr/src/bin/edi.rs | 3 +- cmdr/src/giti/branch/giti_ui_templates.rs | 3 +- .../tui_core/color_wheel/color_wheel_impl.rs | 31 ++-- core/src/tui_core/tui_style/tui_style_impl.rs | 164 ++++++++++++++++++ 5 files changed, 203 insertions(+), 154 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d6807fbde..e9744723a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,89 +1,9 @@ # Changelog - - -- [global-config](#global-config) - - [2024-12-04](#2024-12-04) -- [r3bl-cmdr](#r3bl-cmdr) - - [v_next-release-cmdr](#v_next-release-cmdr) - - [v0.0.16 2024-09-13](#v0016-2024-09-13) - - [v0.0.15 2024-09-12](#v0015-2024-09-12) - - [v0.0.14 2024-06-29](#v0014-2024-06-29) - - [v0.0.13 2024-05-20](#v0013-2024-05-20) - - [v0.0.12 2024-05-12](#v0012-2024-05-12) - - [v0.0.11 2024-01-14](#v0011-2024-01-14) - - [v0.0.10 2024-01-02](#v0010-2024-01-02) - - [v0.0.9 2023-12-31](#v009-2023-12-31) - - [v0.0.8 2023-12-22](#v008-2023-12-22) -- [r3bl_tuify](#r3bl_tuify) - - [v0.2.0 2024-10-21](#v020-2024-10-21) - - [v0.1.27 2024-09-12](#v0127-2024-09-12) - - [v0.1.26 2024-04-15](#v0126-2024-04-15) - - [v0.1.25 2024-01-14](#v0125-2024-01-14) - - [v0.1.24 2023-12-31](#v0124-2023-12-31) - - [v0.1.23 2023-12-22](#v0123-2023-12-22) - - [v0.1.22 2023-12-20](#v0122-2023-12-20) - - [v0.1.21 2023-10-21](#v0121-2023-10-21) - - [v0.1.20 2023-10-21](#v0120-2023-10-21) - - [v0.1.19 2023-10-17](#v0119-2023-10-17) - - [v0.1.18 2023-10-17](#v0118-2023-10-17) - - [v0.1.17 2023-10-14](#v0117-2023-10-14) -- [r3bl_tui](#r3bl_tui) - - [v0.6.0 2024-10-21](#v060-2024-10-21) - - [v0.5.9 2024-09-12](#v059-2024-09-12) - - [v0.5.8 2024-09-07](#v058-2024-09-07) - - [v0.5.7 2024-08-13](#v057-2024-08-13) - - [v0.5.6 2024-06-29](#v056-2024-06-29) - - [v0.5.5 2024-05-20](#v055-2024-05-20) - - [v0.5.4 2024-05-20](#v054-2024-05-20) - - [v0.5.3 2024-04-15](#v053-2024-04-15) - - [v0.5.2 2024-01-14](#v052-2024-01-14) - - [v0.5.1 2024-01-09](#v051-2024-01-09) - - [v0.5.0 2023-12-31](#v050-2023-12-31) - - [v0.4.0 2023-12-22](#v040-2023-12-22) - - [v0.3.10 2023-10-29](#v0310-2023-10-29) - - [v0.3.9 2023-10-29](#v039-2023-10-29) - - [v0.3.7 2023-10-21](#v037-2023-10-21) - - [v0.3.6 2023-10-17](#v036-2023-10-17) - - [v0.3.5 2023-10-14](#v035-2023-10-14) - - [v0.3.3 2023-04-20](#v033-2023-04-20) - - [v0.3.2 2023-03-06](#v032-2023-03-06) - - [v0.3.1 2023-03-06](#v031-2023-03-06) -- [r3bl_core](#r3bl_core) - - [v_next_release_r3bl_core](#v_next_release_r3bl_core) - - [v0.10.0 2024-10-20](#v0100-2024-10-20) -- [r3bl_analytics_schema](#r3bl_analytics_schema) - - [v0.0.2 2024-09-12](#v002-2024-09-12) - - [v0.0.1 2023-12-31](#v001-2023-12-31) -- [r3bl_macro](#r3bl_macro) - - [v0.10.0 2024-10-20](#v0100-2024-10-20) -- [r3bl_test_fixtures](#r3bl_test_fixtures) - - [v_next_release_r3bl_test_fixtures](#v_next_release_r3bl_test_fixtures) - - [v0.1.0 2024-10-21](#v010-2024-10-21) - - [v0.0.3 2024-09-12](#v003-2024-09-12) - - [v0.0.2 2024-07-13](#v002-2024-07-13) - - [v0.0.1 2024-07-12](#v001-2024-07-12) -- [r3bl_terminal_async](#r3bl_terminal_async) - - [v0.6.0 2024-10-21](#v060-2024-10-21) - - [v0.5.7 2024-09-12](#v057-2024-09-12) - - [v0.5.6 2024-08-13](#v056-2024-08-13) - - [v0.5.5 2024-07-13](#v055-2024-07-13) - - [v0.5.4 2024-07-12](#v054-2024-07-12) - - [v0.5.3 2024-05-22](#v053-2024-05-22) - - [v0.5.2 2020-05-06](#v052-2020-05-06) - - [v0.5.1 2024-04-28](#v051-2024-04-28) - - [v0.5.0 2024-04-22](#v050-2024-04-22) - - [v0.4.0 2024-04-21](#v040-2024-04-21) - - [v0.3.1 2024-04-17](#v031-2024-04-17) - - [v0.3.0 2024-04-15](#v030-2024-04-15) -- [r3bl_ansi_color](#r3bl_ansi_color) - - [v0.7.0 2024-10-18](#v070-2024-10-18) - - - [global-config](#global-config) - [-12-04](#-12-04) - [r3bl-cmdr](#r3bl-cmdr) - - [next-release-cmdr](#next-release-cmdr) + - [next](#v_next_release_cmdr) - [v0.0.16 2024-09-13](#v0016-2024-09-13) - [v0.0.15 2024-09-12](#v0015-2024-09-12) - [v0.0.14 2024-06-29](#v0014-2024-06-29) @@ -128,7 +48,7 @@ - [v0.3.2 2023-03-06](#v032-2023-03-06) - [v0.3.1 2023-03-06](#v031-2023-03-06) - [r3bl_core](#r3bl_core) - - [next_release_r3bl_core](#next_release_r3bl_core) + - [next](#v_next_release_r3bl_core) - [v0.10.0 2024-10-20](#v0100-2024-10-20) - [r3bl_analytics_schema](#r3bl_analytics_schema) - [v0.0.2 2024-09-12](#v002-2024-09-12) @@ -136,6 +56,7 @@ - [r3bl_macro](#r3bl_macro) - [v0.10.0 2024-10-20](#v0100-2024-10-20) - [r3bl_test_fixtures](#r3bl_test_fixtures) + - [next](#v_next_release_r3bl_test_fixtures) - [v0.1.0 2024-10-21](#v010-2024-10-21) - [v0.0.3 2024-09-12](#v003-2024-09-12) - [v0.0.2 2024-07-13](#v002-2024-07-13) @@ -206,50 +127,6 @@ - [v0.9.11 2023-10-28](#v0911-2023-10-28) - [v0.9.10 2023-10-21](#v0910-2023-10-21) - [v0.9.9](#v099) - -12-22](#v098-2023-12-22) - - [v0.9.7 2023-10-21](#v097-2023-10-21) - - [v0.9.6 2023-10-17](#v096-2023-10-17) - - [v0.9.5 2023-10-14](#v095-2023-10-14) -- [r3bl_rs_utils_core](#r3bl_rs_utils_core) - - [Rename to r3bl_core](#rename-to-r3bl_core) - - [v0.9.16 2024-09-12](#v0916-2024-09-12) - - [v0.9.15 2024-09-07](#v0915-2024-09-07) - - [v0.9.14 2024-08-13](#v0914-2024-08-13) - - [v0.9.13 2024-04-15](#v0913-2024-04-15) - - [v0.9.12 2024-01-07](#v0912-2024-01-07) - - [v0.9.11 2024-01-02](#v0911-2024-01-02) - - [v0.9.10 2023-12-22](#v0910-2023-12-22) - - [v0.9.9 2023-10-21](#v099-2023-10-21) - - [v0.9.8 2023-10-21](#v098-2023-10-21) - - [v0.9.7 2023-10-17](#v097-2023-10-17) - - [v0.9.6 2023-10-17](#v096-2023-10-17) - - [v0.9.5 2023-10-14](#v095-2023-10-14) - - [v0.9.1 2023-03-06](#v091-2023-03-06) -- [r3bl_simple_logger](#r3bl_simple_logger) - - [Archived 2024-09-27](#archived-2024-09-27) - - [v0.1.4 2024-09-12](#v014-2024-09-12) - - [v0.1.3 2023-10-21](#v013-2023-10-21) - - [v0.1.2 2023-10-21](#v012-2023-10-21) - - [v0.1.1 2023-10-17](#v011-2023-10-17) - - [v0.1.0 2023-10-14](#v010-2023-10-14) -- [r3bl_redux](#r3bl_redux) - - [Archived 2024-09-29](#archived-2024-09-29) - - [v0.2.8 2024-09-12](#v028-2024-09-12) - - [v0.2.7 2024-09-07](#v027-2024-09-07) - - [v0.2.6 2023-10-21](#v026-2023-10-21) - - [v0.2.5 2023-10-17](#v025-2023-10-17) - - [v0.2.4 2023-10-14](#v024-2023-10-14) -- [r3bl_rs_utils](#r3bl_rs_utils) - - [Archived 2024-09-30](#archived-2024-09-30) - - [v0.9.16 2024-09-12](#v0916-2024-09-12) - - [v0.9.15 2023-12-22](#v0915-2023-12-22) - - [v0.9.14 2023-10-29](#v0914-2023-10-29) - - [v0.9.13 2023-10-29](#v0913-2023-10-29) - - [v0.9.12 2023-10-29](#v0912-2023-10-29) - - [v0.9.11 2023-10-28](#v0911-2023-10-28) - - [v0.9.10 2023-10-21](#v0910-2023-10-21) - - [v0.9.9](#v099) - [Renamed](#renamed) - [r3bl_rs_utils_macro](#r3bl_rs_utils_macro) - [r3bl_rs_utils_core](#r3bl_rs_utils_core) @@ -259,8 +136,6 @@ - [r3bl_rs_utils](#r3bl_rs_utils) - [More info on changelogs](#more-info-on-changelogs) - - ## `global-config` @@ -289,7 +164,7 @@ the following: ## `r3bl-cmdr` -### v_next-release-cmdr +### v_next_release_cmdr This is part of a total reorganization of the `r3bl-open-core` repo. This is a breaking change for almost every crate in the repo. This @@ -880,12 +755,18 @@ exhaustively tested and is able to handle many more corner cases. ### v_next_release_r3bl_core -This release does not have any major changes. -1. Add a new declarative macro to effortlessly create global mutable thread safe - singletons (without using `unsafe`). -2. Replace all the ignored doc tests with `no_run` (just compile) or compile and run. For - all Rust source files (in the entire monorepo, and not just this crate / folder). -3. Here's the [PR](https://github.com/r3bl-org/r3bl-open-core/pull/370). +This release does not have any major changes. Here are the highlights: +- [PR](https://github.com/r3bl-org/r3bl-open-core/pull/370/commits/20fe5e730a0f592c203c85a68ee6e5b345136f44) + 1. Add a new declarative macro to effortlessly create global mutable thread safe + singletons (without using `unsafe`). + 2. Replace all the ignored doc tests with `no_run` (just compile) or compile and run. For + all Rust source files (in the entire monorepo, and not just this crate / folder). +- [PR](https://github.com/r3bl-org/r3bl-open-core/pull/376/commits/39bf421bb86d4de004bffd08f35df12ce3ef8541) + 1. There's a new converter `convert_to_ansi_color_styles` which converts a `TuiStyle` into + a `Vec` of `r3bl_ansi_term::Style`. + 2. This is for `lolcat_api` enhancements which now + allow for an optional default style to be passed in, that will be applied to the + generated lolcat output. Changed: - Fix all the Rust doc tests that were marked with `ignore`. Remove the `ignore` with @@ -897,6 +778,11 @@ Changed: replace them with doc comments that compile successfully. - Added: + - `lolcat_api` enhancements that now allow for an optional default style to be passed in + to `ColorWheel::lolcat_into_string` and `ColorWheel::colorize_into_string`, that will + be applied to the generated lolcat output. + - `convert_to_ansi_color_styles` module that adds the ability to convert a `TuiStyle` + into a `Vec` of `r3bl_ansi_term::Style`. - A new declarative macro `create_global_singleton!` that takes a struct (which must implement `Default` trait) and allows it to be simply turned into a singleton. - You can still use the struct directly. Or just use the supplied generated associated diff --git a/cmdr/src/bin/edi.rs b/cmdr/src/bin/edi.rs index 732cc5827..386ee4645 100644 --- a/cmdr/src/bin/edi.rs +++ b/cmdr/src/bin/edi.rs @@ -130,6 +130,7 @@ pub mod edi_ui_templates { &UnicodeString::from("New version of edi is available 📦."), GradientGenerationPolicy::ReuseExistingGradientAndResetIndex, TextColorizationPolicy::ColorEachCharacter(None), + None, ) }; @@ -168,7 +169,7 @@ pub mod edi_ui_templates { let plain_text_exit_msg = format!("{goodbye_to_user}\n{please_star_us}"); - ColorWheel::lolcat_into_string(&plain_text_exit_msg) + ColorWheel::lolcat_into_string(&plain_text_exit_msg, None) }); } } diff --git a/cmdr/src/giti/branch/giti_ui_templates.rs b/cmdr/src/giti/branch/giti_ui_templates.rs index df75fc730..4c99de49a 100644 --- a/cmdr/src/giti/branch/giti_ui_templates.rs +++ b/cmdr/src/giti/branch/giti_ui_templates.rs @@ -109,6 +109,7 @@ pub fn show_exit_message() { &UnicodeString::from(plain_text_exit_msg), GradientGenerationPolicy::ReuseExistingGradientAndResetIndex, TextColorizationPolicy::ColorEachCharacter(None), + None, ) }); } else { @@ -123,7 +124,7 @@ pub fn show_exit_message() { let please_star_us = PleaseStarUs.to_string(); let plain_text_exit_msg = format!("{goodbye_to_user}\n{please_star_us}"); - ColorWheel::lolcat_into_string(&plain_text_exit_msg) + ColorWheel::lolcat_into_string(&plain_text_exit_msg, None) }); } } diff --git a/core/src/tui_core/color_wheel/color_wheel_impl.rs b/core/src/tui_core/color_wheel/color_wheel_impl.rs index 2cdf9e77d..7f792dacf 100644 --- a/core/src/tui_core/color_wheel/color_wheel_impl.rs +++ b/core/src/tui_core/color_wheel/color_wheel_impl.rs @@ -15,6 +15,8 @@ * limitations under the License. */ +use std::ops::AddAssign; + use r3bl_ansi_color::AnsiStyledText; use serde::{Deserialize, Serialize}; @@ -24,7 +26,7 @@ use super::{ColorWheelConfig, GradientKind, GradientLengthKind}; use crate::{ch, - convert_tui_color_into_r3bl_ansi_color, + convert_to_ansi_color_styles, generate_random_truecolor_gradient, generate_truecolor_gradient, get_gradient_array_for, @@ -334,11 +336,15 @@ impl ColorWheel { } /// Simplified version of [ColorWheel::colorize_into_string] with some defaults. - pub fn lolcat_into_string(text: &str) -> String { + pub fn lolcat_into_string( + text: &str, + maybe_default_style: Option, + ) -> String { ColorWheel::default().colorize_into_string( &UnicodeString::from(text), GradientGenerationPolicy::ReuseExistingGradientAndResetIndex, TextColorizationPolicy::ColorEachCharacter(None), + maybe_default_style, ) } @@ -348,6 +354,7 @@ impl ColorWheel { unicode_string: &UnicodeString, gradient_generation_policy: GradientGenerationPolicy, text_colorization_policy: TextColorizationPolicy, + maybe_default_style: Option, ) -> String { let it = self.colorize_into_styled_texts( unicode_string, @@ -358,26 +365,15 @@ impl ColorWheel { let mut acc_vec = vec![]; for TuiStyledText { - style, + mut style, text: unicode_string, } in it.inner { - let maybe_src_color_fg = style.color_fg; - let maybe_src_color_bg = style.color_bg; - - let mut acc_style = vec![]; - - if let Some(src_color_fg) = maybe_src_color_fg { - acc_style.push(r3bl_ansi_color::Style::Foreground( - convert_tui_color_into_r3bl_ansi_color(src_color_fg), - )); + if let Some(default_style) = maybe_default_style { + style.add_assign(default_style); } - if let Some(src_color_bg) = maybe_src_color_bg { - acc_style.push(r3bl_ansi_color::Style::Background( - convert_tui_color_into_r3bl_ansi_color(src_color_bg), - )); - } + let acc_style = convert_to_ansi_color_styles::from_tui_style(style); let ansi_styled_text = AnsiStyledText { style: &acc_style, @@ -935,6 +931,7 @@ mod tests_color_wheel_rgb { &unicode_string, GradientGenerationPolicy::RegenerateGradientAndIndexBasedOnTextLength, TextColorizationPolicy::ColorEachCharacter(None), + None, ); println!("ansi_styled_string: {}", ansi_styled_string); diff --git a/core/src/tui_core/tui_style/tui_style_impl.rs b/core/src/tui_core/tui_style/tui_style_impl.rs index d2ab1d184..2af8e8303 100644 --- a/core/src/tui_core/tui_style/tui_style_impl.rs +++ b/core/src/tui_core/tui_style/tui_style_impl.rs @@ -348,3 +348,167 @@ mod test_style { assert!(!style.reverse); } } + +pub mod convert_to_ansi_color_styles { + use super::*; + use crate::convert_tui_color_into_r3bl_ansi_color; + + pub fn from_tui_style(tui_style: TuiStyle) -> Vec { + let mut acc_style: Vec = vec![]; + + if let Some(color_fg) = tui_style.color_fg { + acc_style.push(r3bl_ansi_color::Style::Foreground( + convert_tui_color_into_r3bl_ansi_color(color_fg), + )); + } + + if let Some(color_bg) = tui_style.color_bg { + acc_style.push(r3bl_ansi_color::Style::Background( + convert_tui_color_into_r3bl_ansi_color(color_bg), + )); + } + + if tui_style.bold { + acc_style.push(r3bl_ansi_color::Style::Bold); + } + + if tui_style.dim { + acc_style.push(r3bl_ansi_color::Style::Dim); + } + + if tui_style.italic { + acc_style.push(r3bl_ansi_color::Style::Italic); + } + + if tui_style.underline { + acc_style.push(r3bl_ansi_color::Style::Underline); + } + + if tui_style.reverse { + acc_style.push(r3bl_ansi_color::Style::Invert); + } + + if tui_style.hidden { + acc_style.push(r3bl_ansi_color::Style::Hidden); + } + + if tui_style.strikethrough { + acc_style.push(r3bl_ansi_color::Style::Strikethrough); + } + + acc_style + } + + #[cfg(test)] + mod tests_style { + use super::*; + use crate::{assert_eq2, color, ANSIBasicColor}; + + #[test] + fn test_all_fields_in_style() { + let style = TuiStyle { + id: 1, + bold: true, + dim: true, + underline: true, + reverse: true, + hidden: true, + strikethrough: true, + color_fg: color!(@red).into(), + color_bg: color!(0, 0, 0).into(), + padding: Some(ch!(10)), + ..TuiStyle::default() + }; + + assert!(!style.computed); + assert_eq2!(style.id, 1); + assert!(style.bold); + assert!(style.dim); + assert!(style.underline); + assert!(style.reverse); + assert!(style.hidden); + assert!(style.strikethrough); + assert_eq2!(style.color_fg, color!(@red).into()); + assert_eq2!(style.color_bg, color!(0, 0, 0).into()); + assert_eq2!(style.padding, Some(ch!(10))); + } + + #[test] + fn test_style() { + let style = TuiStyle { + id: 1, + color_fg: color!(0, 0, 0).into(), + color_bg: color!(0, 0, 0).into(), + bold: true, + dim: true, + italic: true, + ..TuiStyle::default() + }; + + dbg!(&style); + + assert!(style.bold); + assert!(style.dim); + assert!(style.italic); + assert!(!style.underline); + assert!(!style.strikethrough); + assert!(!style.reverse); + } + + #[test] + fn test_add_styles() { + let style1 = TuiStyle { + bold: true, + color_fg: color!(@red).into(), + ..TuiStyle::default() + }; + + let style2 = TuiStyle { + italic: true, + color_bg: color!(0, 0, 0).into(), + ..TuiStyle::default() + }; + + let combined_style = style1 + style2; + + assert!(combined_style.bold); + assert!(combined_style.italic); + assert_eq2!(combined_style.color_fg, color!(@red).into()); + assert_eq2!(combined_style.color_bg, color!(0, 0, 0).into()); + } + + #[test] + fn test_add_assign_styles() { + let mut style1 = TuiStyle { + bold: true, + color_fg: color!(@red).into(), + ..TuiStyle::default() + }; + + let style2 = TuiStyle { + italic: true, + color_bg: color!(0, 0, 0).into(), + ..TuiStyle::default() + }; + + style1 += style2; + + assert!(style1.bold); + assert!(style1.italic); + assert_eq2!(style1.color_fg, color!(@red).into()); + assert_eq2!(style1.color_bg, color!(0, 0, 0).into()); + } + + #[test] + fn test_remove_bg_color() { + let mut style = TuiStyle { + color_bg: color!(0, 0, 0).into(), + ..TuiStyle::default() + }; + + style.remove_bg_color(); + + assert!(style.color_bg.is_none()); + } + } +}