From 63b0dd83468f160039ba0e6209ea6df1ebc29d9a Mon Sep 17 00:00:00 2001 From: Nazmul Idris Date: Sat, 24 Feb 2024 21:35:58 -0600 Subject: [PATCH] [core, tui] Refactor Cargo.toml and remove syntect from core, change all ambiguous names to be explicit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is an attempt to isolate the use of syntect to just 1 crate: r3bl_tui. It has been removed from the core crate. However, it is not possible to remove syntect from the lolcat / color_wheel modules as they are intrinsically tied together. Basically, they need to be able to render output, and for that they need to be in the r3bl_tui crate which has a dependency on syntect and this can't be removed. safemem is no longer maintained, you can see the following output from running cargo deny check advisories. 180 │ safemem 0.3.3 registry+https://github.com/rust-lang/crates.io-index │ ------------------------------------------------------------------- unmaintained advisory detected │ = ID: RUSTSEC-2023-0081 = Advisory: https://rustsec.org/advisories/RUSTSEC-2023-0081 = The latest crates.io release was in 2019. The repository has been archived by the author. = Announcement: https://github.com/abonander/safemem = Solution: No safe upgrade is available! = safemem v0.3.3 └── line-wrap v0.1.1 └── plist v1.6.0 └── syntect v5.1.0 └── r3bl_tui v0.5.2 └── r3bl-cmdr v0.0.11 More info: - https://github.com/r3bl-org/r3bl-open-core/pull/314 - https://github.com/ebarnard/rust-plist/pull/134 - https://github.com/trishume/syntect/issues/521 This `safemem` issue is resolved since the dependencies of syntect, `line-wrap` and `plist` are both updated. By pinning the version of `plist` to `1.6.1` (`cargo update -p plist --precise 1.6.1`) and checking in `Cargo.toml`, this resolves the `safemem` issue. --- .vscode/settings.json | 1 + Cargo.lock | 1 - analytics_schema/src/analytics_data.rs | 7 + ansi_color/src/detect_color_support.rs | 2 + .../analytics_client.rs | 38 +-- cmdr/src/analytics_client/mod.rs | 24 -- cmdr/src/bin/edi.rs | 11 +- cmdr/src/bin/giti.rs | 23 +- cmdr/src/edi/app_main.rs | 114 ++++---- cmdr/src/edi/state.rs | 23 +- cmdr/src/giti/branch/checkout.rs | 10 +- cmdr/src/giti/branch/delete.rs | 15 +- cmdr/src/giti/branch/giti_ui_templates.rs | 6 +- cmdr/src/giti/branch/new.rs | 2 +- cmdr/src/giti/clap_config.rs | 141 +++++----- cmdr/src/giti/common_types.rs | 2 +- cmdr/src/giti/ui_strings.rs | 257 +++++++++--------- cmdr/src/lib.rs | 1 + core/Cargo.toml | 3 - core/src/tui_core/dimens/ch_unit.rs | 6 +- core/src/tui_core/graphemes/range.rs | 2 +- .../tui_core/graphemes/test_unicode_string.rs | 2 +- core/src/tui_core/graphemes/unicode_string.rs | 2 +- core/src/tui_core/styles/mod.rs | 8 +- .../styles/{style.rs => tui_style.rs} | 103 +++---- .../{stylesheet.rs => tui_stylesheet.rs} | 68 ++--- deny.toml | 2 - macro/src/lib.rs | 16 +- macro/src/make_style/codegen.rs | 2 +- simple_logger/examples/rgb_colors.rs | 1 - .../demo/ex_app_no_layout/app_main.rs | 16 +- .../demo/ex_app_no_layout/launcher.rs | 2 +- .../demo/ex_app_with_1col_layout/app_main.rs | 40 ++- .../demo/ex_app_with_2col_layout/app_main.rs | 44 ++- tui/examples/demo/ex_editor/app_main.rs | 69 +++-- tui/examples/demo/ex_pitch/app_main.rs | 30 +- tui/examples/demo/ex_rc/app_main.rs | 33 ++- .../color_wheel/ansi_256_color_gradients.rs | 2 +- tui/src/tui/color_wheel/color_wheel_struct.rs | 99 ++++--- tui/src/tui/color_wheel/mod.rs | 4 +- tui/src/tui/color_wheel/truecolor_gradient.rs | 6 +- .../{styled_text.rs => tui_styled_text.rs} | 90 +++--- .../dialog_component_struct.rs | 4 +- .../dialog/dialog_engine/dialog_engine_api.rs | 22 +- .../dialog_engine/dialog_engine_struct.rs | 8 +- .../editor_buffer_clipboard_support.rs | 4 +- .../editor_buffer/editor_buffer_struct.rs | 32 +-- .../editor_component_struct.rs | 6 +- .../editor/editor_engine/editor_engine_api.rs | 30 +- .../editor_engine_internal_api.rs | 58 ++-- tui/src/tui/editor/test_editor.rs | 6 +- tui/src/tui/layout/flex_box.rs | 8 +- tui/src/tui/layout/layout_error.rs | 2 +- tui/src/tui/layout/layout_management.rs | 2 +- tui/src/tui/layout/surface.rs | 19 +- .../tui/layout/test_surface_2_col_complex.rs | 24 +- .../tui/layout/test_surface_2_col_simple.rs | 20 +- tui/src/tui/lolcat/lolcat_api.rs | 12 +- tui/src/tui/lolcat/lolcat_impl.rs | 24 +- .../parse_block_markdown_text_until_eol.rs | 2 +- tui/src/tui/md_parser/parse_element.rs | 36 ++- tui/src/tui/md_parser/parser.rs | 2 +- tui/src/tui/rsx/layout_macros.rs | 4 +- ...nvert_syntect_highlighting_to_tui_style.rs | 37 +++ .../syntax_highlighting/intermediate_types.rs | 26 +- .../md_parser_syn_hi/md_parser_stylesheet.rs | 72 ++--- .../md_parser_syn_hi/md_parser_syn_hi_impl.rs | 86 +++--- tui/src/tui/syntax_highlighting/mod.rs | 2 + .../syntax_highlighting/pattern_matcher.rs | 2 +- .../syntect_to_styled_text_conversion.rs | 17 +- .../test_r3bl_syntect_theme.rs | 5 +- .../crossterm_backend/debug.rs | 4 +- .../offscreen_buffer_paint_impl.rs | 10 +- .../crossterm_backend/render_op_impl.rs | 30 +- ...verter.rs => crossterm_color_converter.rs} | 6 +- tui/src/tui/terminal_lib_backends/mod.rs | 4 +- .../terminal_lib_backends/offscreen_buffer.rs | 12 +- .../tui/terminal_lib_backends/render_op.rs | 8 +- .../render_pipeline_to_offscreen_buffer.rs | 88 +++--- .../tui/terminal_window/main_event_loop.rs | 48 ++-- .../terminal_window/manage_focus/has_focus.rs | 17 +- tui/src/tui/test_make_style_macro.rs | 22 +- tui/src/tui/test_style.rs | 46 ++-- tuify/examples/main_interactive.rs | 16 +- tuify/examples/single_select_quiz_game.rs | 37 ++- tuify/src/bin/rt.rs | 6 +- tuify/src/components/select_component.rs | 67 ++--- tuify/src/event_loop.rs | 2 +- tuify/src/function_component.rs | 2 +- tuify/src/public_api.rs | 12 +- tuify/src/test_utils.rs | 8 +- utils/src/tree_memory_arena/arena.rs | 3 +- utils/src/tree_memory_arena/mt_arena.rs | 1 - 93 files changed, 1163 insertions(+), 1186 deletions(-) rename cmdr/src/{analytics_client => }/analytics_client.rs (94%) delete mode 100644 cmdr/src/analytics_client/mod.rs rename core/src/tui_core/styles/{style.rs => tui_style.rs} (78%) rename core/src/tui_core/styles/{stylesheet.rs => tui_stylesheet.rs} (71%) rename tui/src/tui/color_wheel/{styled_text.rs => tui_styled_text.rs} (91%) create mode 100644 tui/src/tui/syntax_highlighting/convert_syntect_highlighting_to_tui_style.rs rename tui/src/tui/terminal_lib_backends/{color_converter.rs => crossterm_color_converter.rs} (97%) diff --git a/.vscode/settings.json b/.vscode/settings.json index 0fbbb968..c8b54fff 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -121,6 +121,7 @@ "undos", "uninteractive", "unspecial", + "unstaged", "withmutreturns", "Zoey" ] diff --git a/Cargo.lock b/Cargo.lock index fef20e46..05cd33a4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1555,7 +1555,6 @@ dependencies = [ "rand", "serde", "serde_json", - "syntect", "time", "unicode-segmentation", "unicode-width", diff --git a/analytics_schema/src/analytics_data.rs b/analytics_schema/src/analytics_data.rs index e99d1c6c..e89f08f1 100644 --- a/analytics_schema/src/analytics_data.rs +++ b/analytics_schema/src/analytics_data.rs @@ -25,6 +25,12 @@ pub struct AnalyticsRecord { pub events: Vec, } +impl Default for AnalyticsRecord { + fn default() -> Self { + Self::new() + } +} + impl AnalyticsRecord { pub fn new() -> AnalyticsRecord { let events = Vec::new(); @@ -53,6 +59,7 @@ pub struct AnalyticsEvent { impl AnalyticsEvent { /// This is meant to be called on the client, before the data is sent to the server. /// The time is not set here since it will be set on the server-side. + #[allow(clippy::new_ret_no_self)] pub fn new( proxy_user_id: String, proxy_machine_id: String, diff --git a/ansi_color/src/detect_color_support.rs b/ansi_color/src/detect_color_support.rs index 19061994..18dafa88 100644 --- a/ansi_color/src/detect_color_support.rs +++ b/ansi_color/src/detect_color_support.rs @@ -58,6 +58,7 @@ pub mod global_color_support { /// function. In any test in which this function is called, please use the `#[serial]` /// attribute to annotate that test. Otherwise there will be flakiness in the test results /// (tests are run in parallel using many threads). + #[allow(clippy::result_unit_err)] pub fn set_override(value: ColorSupport) { let it = i8::from(value); unsafe { COLOR_SUPPORT_GLOBAL.store(it, Ordering::SeqCst) } @@ -71,6 +72,7 @@ pub mod global_color_support { /// - If the value has been set using [global_color_support::set_override], then that /// value will be returned. /// - Otherwise, an error will be returned. + #[allow(clippy::result_unit_err)] pub fn try_get_override() -> Result { let it = unsafe { COLOR_SUPPORT_GLOBAL.load(Ordering::SeqCst) }; ColorSupport::try_from(it) diff --git a/cmdr/src/analytics_client/analytics_client.rs b/cmdr/src/analytics_client.rs similarity index 94% rename from cmdr/src/analytics_client/analytics_client.rs rename to cmdr/src/analytics_client.rs index 32432bbe..ba05c60b 100644 --- a/cmdr/src/analytics_client/analytics_client.rs +++ b/cmdr/src/analytics_client.rs @@ -34,8 +34,6 @@ use r3bl_rs_utils_core::{call_if_true, CommonResult}; use reqwest::{Client, Response}; -use crate::DEBUG_ANALYTICS_CLIENT_MOD; - #[derive(Clone, Copy, Debug, PartialEq)] pub enum AnalyticsAction { GitiBranchDelete, @@ -49,8 +47,8 @@ pub enum AnalyticsAction { MachineIdProxyCreate, } -impl AnalyticsAction { - pub fn to_string(&self) -> String { +impl std::fmt::Display for AnalyticsAction { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { #[rustfmt::skip] let action = match self { AnalyticsAction::GitiAppStart => "giti app start", @@ -63,32 +61,34 @@ impl AnalyticsAction { AnalyticsAction::EdiFileSave => "edi file save", AnalyticsAction::MachineIdProxyCreate => "proxy machine id create", }; - action.to_string() + write!(f, "{}", action) } } pub mod config_folder { + use std::fmt::{Display, Formatter, Result}; + use super::*; + use crate::DEBUG_ANALYTICS_CLIENT_MOD; pub enum ConfigPaths { R3BLTopLevelFolderName, ProxyMachineIdFile, } - impl ConfigPaths { - pub fn to_string(&self) -> String { + impl Display for ConfigPaths { + fn fmt(&self, f: &mut Formatter<'_>) -> Result { let path = match self { ConfigPaths::R3BLTopLevelFolderName => "r3bl-cmdr", ConfigPaths::ProxyMachineIdFile => "id", }; - path.to_string() + write!(f, "{}", path) } } /// This is where the config file is stored. pub fn get_id_file_path(path: PathBuf) -> PathBuf { - let id_file_path = path.join(ConfigPaths::ProxyMachineIdFile.to_string()); - id_file_path + path.join(ConfigPaths::ProxyMachineIdFile.to_string()) } /// This is where the config folder is. @@ -172,6 +172,7 @@ pub mod file_io { pub mod proxy_machine_id { use super::*; + use crate::DEBUG_ANALYTICS_CLIENT_MOD; /// Read the file contents from [config_folder::get_id_file_path] and return it as a /// string if it exists and can be read. @@ -190,7 +191,7 @@ pub mod proxy_machine_id { .to_string(), ); }); - return contents; + contents } Err(_) => { let new_id = friendly_random_id::generate_friendly_random_id(); @@ -223,13 +224,11 @@ pub mod proxy_machine_id { ); } } - return new_id; + new_id } } } - Err(_) => { - return friendly_random_id::generate_friendly_random_id(); - } + Err(_) => friendly_random_id::generate_friendly_random_id(), } } } @@ -358,6 +357,7 @@ pub mod upgrade_check { pub mod http_client { use super::*; + use crate::DEBUG_ANALYTICS_CLIENT_MOD; pub async fn make_get_request(url: &str) -> Result { let client = Client::new(); @@ -371,7 +371,7 @@ pub mod http_client { .to_string(), ); }); - return Ok(response); + Ok(response) } else { // Handle error response. log_error( @@ -379,7 +379,7 @@ pub mod http_client { .red() .to_string(), ); - return response.error_for_status(); + response.error_for_status() } } @@ -398,7 +398,7 @@ pub mod http_client { .to_string(), ); }); - return Ok(response); + Ok(response) } else { // Handle error response. log_error( @@ -406,7 +406,7 @@ pub mod http_client { .red() .to_string(), ); - return response.error_for_status(); + response.error_for_status() } } } diff --git a/cmdr/src/analytics_client/mod.rs b/cmdr/src/analytics_client/mod.rs deleted file mode 100644 index 3881adda..00000000 --- a/cmdr/src/analytics_client/mod.rs +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (c) 2023 R3BL LLC - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -pub const DEBUG_ANALYTICS_CLIENT_MOD: bool = true; - -// Attach. -pub mod analytics_client; - -// Re-exports. -pub use analytics_client::*; diff --git a/cmdr/src/bin/edi.rs b/cmdr/src/bin/edi.rs index c47529d4..0111f0d6 100644 --- a/cmdr/src/bin/edi.rs +++ b/cmdr/src/bin/edi.rs @@ -70,17 +70,17 @@ async fn main() -> CommonResult<()> { ); launcher::run_app(Some(cli_arg.file_paths[0].clone())).await?; } - _ => match edi_ui_templates::handle_multiple_files_not_supported_yet(cli_arg) - { - Some(file_path) => { + _ => { + if let Some(file_path) = + edi_ui_templates::handle_multiple_files_not_supported_yet(cli_arg) + { report_analytics::start_task_to_generate_event( "".to_string(), AnalyticsAction::EdiFileOpenMultiple, ); launcher::run_app(Some(file_path)).await?; } - _ => {} - }, + } } // Stop logging. @@ -95,7 +95,6 @@ async fn main() -> CommonResult<()> { pub mod edi_ui_templates { use r3bl_ansi_color::{AnsiStyledText, Style}; - use r3bl_cmdr::upgrade_check; use r3bl_tuify::{select_from_list, SelectionMode, StyleSheet, diff --git a/cmdr/src/bin/giti.rs b/cmdr/src/bin/giti.rs index 01b629e0..eaed7da0 100644 --- a/cmdr/src/bin/giti.rs +++ b/cmdr/src/bin/giti.rs @@ -19,14 +19,9 @@ //! use clap::Parser; -use giti::{branch::{checkout::try_checkout_branch, delete::try_delete_branch}, - *}; use r3bl_ansi_color::{AnsiStyledText, Style}; use r3bl_cmdr::{color_constants::DefaultColors::{FrozenBlue, GuardsRed, MoonlightBlue}, - giti::{self, - clap_config::clap_config::{BranchSubcommand, - CLIArg, - CLICommand}}, + giti::{clap_config::*, *}, report_analytics, upgrade_check, AnalyticsAction}; @@ -107,7 +102,7 @@ pub fn launch_giti(cli_arg: CLIArg) { ); log_error(err_msg.clone()); AnsiStyledText { - text: &format!("{err_msg}",), + text: &err_msg.to_string(), style: &[Style::Foreground(GuardsRed.as_ansi_color())], } .println(); @@ -125,21 +120,17 @@ pub fn try_run_command( .. } => match command_to_run_with_each_selection { Some(subcommand) => match subcommand { - BranchSubcommand::Delete => return try_delete_branch(), + BranchSubcommand::Delete => try_delete_branch(), BranchSubcommand::Checkout => { - return try_checkout_branch(maybe_branch_name.clone()) - } - BranchSubcommand::New => { - return try_make_new_branch(maybe_branch_name.clone()) + try_checkout_branch(maybe_branch_name.clone()) } + BranchSubcommand::New => try_make_new_branch(maybe_branch_name.clone()), }, - _ => { - return user_typed_giti_branch(); - } + _ => user_typed_giti_branch(), }, CLICommand::Commit {} => unimplemented!(), CLICommand::Remote {} => unimplemented!(), - }; + } } fn user_typed_giti_branch() -> CommonResult { diff --git a/cmdr/src/edi/app_main.rs b/cmdr/src/edi/app_main.rs index 6e267d97..a2f13a89 100644 --- a/cmdr/src/edi/app_main.rs +++ b/cmdr/src/edi/app_main.rs @@ -19,7 +19,7 @@ use std::fmt::*; use crossterm::style::Stylize; use r3bl_rs_utils_core::*; -use r3bl_rs_utils_macro::style; +use r3bl_rs_utils_macro::tui_style; use r3bl_tui::*; use tokio::sync::mpsc::Sender; @@ -90,7 +90,7 @@ mod app_main_constructor { impl AppMain { /// Note that this needs to be initialized before it can be used. pub fn new_boxed() -> BoxedSafeApp { - let it = Self::default(); + let it = Self; Box::new(it) } } @@ -173,7 +173,7 @@ mod app_main_impl_app_trait { // If modal not activated, route the input event to the focused component. ComponentRegistry::route_event_to_focused_component( global_data, - input_event.clone(), + input_event, component_registry_map, has_focus, ) @@ -232,23 +232,20 @@ mod app_main_impl_app_trait { ), ); - match modal_dialog_ask_for_filename_to_save_file::show( + if let Err(err) = modal_dialog_ask_for_filename_to_save_file::show( component_registry_map, has_focus, state, ) { - Err(err) => { - if let Some(CommonError { - err_type: _, - err_msg: msg, - }) = err.downcast_ref::() - { - log_error(format!( - "📣 Error activating simple modal: {msg:?}" - )); - } + if let Some(CommonError { + err_type: _, + err_msg: msg, + }) = err.downcast_ref::() + { + log_error(format!( + "📣 Error activating simple modal: {msg:?}" + )); } - _ => {} }; return Ok(EventPropagation::ConsumedRender); @@ -308,7 +305,7 @@ mod modal_dialog_ask_for_filename_to_save_file { pub fn initialize(state: &mut State, id: FlexBoxId, title: String, text: String) { let new_dialog_buffer = { let mut it = DialogBuffer::new_empty(); - it.title = title.into(); + it.title = title; let line: String = { if text.is_empty() { "".to_string() @@ -362,10 +359,10 @@ mod modal_dialog_ask_for_filename_to_save_file { let dialog_options = DialogEngineConfigOptions { mode: DialogEngineMode::ModalSimple, - maybe_style_border: get_style! { @from_result: result_stylesheet , Id::StyleDialogBorder.into() }, - maybe_style_title: get_style! { @from_result: result_stylesheet , Id::StyleDialogTitle.into() }, - maybe_style_editor: get_style! { @from_result: result_stylesheet , Id::StyleDialogEditor.into() }, - maybe_style_results_panel: get_style! { @from_result: result_stylesheet , Id::StyleDialogResultsPanel.into() }, + maybe_style_border: get_tui_style! { @from_result: result_stylesheet , Id::StyleDialogBorder.into() }, + maybe_style_title: get_tui_style! { @from_result: result_stylesheet , Id::StyleDialogTitle.into() }, + maybe_style_editor: get_tui_style! { @from_result: result_stylesheet , Id::StyleDialogEditor.into() }, + maybe_style_results_panel: get_tui_style! { @from_result: result_stylesheet , Id::StyleDialogResultsPanel.into() }, ..Default::default() }; @@ -403,7 +400,7 @@ mod modal_dialog_ask_for_filename_to_save_file { ); let user_input_file_path = text.trim().to_string(); - if user_input_file_path != "" { + if !user_input_file_path.is_empty() { call_if_true!(DEBUG_TUI_MOD, { let msg = format!("\n💾💾💾 About to save the new buffer with given filename: {user_input_file_path:?}") .magenta() @@ -415,27 +412,24 @@ mod modal_dialog_ask_for_filename_to_save_file { FlexBoxId::from(Id::ComponentEditor), ); - match maybe_editor_buffer { - Some(editor_buffer) => { - // Set the file path. - editor_buffer.editor_content.maybe_file_path = - Some(user_input_file_path.clone()); - - // Set the file extension. - editor_buffer.editor_content.maybe_file_extension = - Some(file_utils::get_file_extension(&Some( - user_input_file_path.clone(), - ))); - - // Fire a signal to save the file. - send_signal!( - main_thread_channel_sender, - TerminalWindowMainThreadSignal::ApplyAction( - AppSignal::SaveFile - ) - ); - } - _ => {} + if let Some(editor_buffer) = maybe_editor_buffer { + // Set the file path. + editor_buffer.editor_content.maybe_file_path = + Some(user_input_file_path.clone()); + + // Set the file extension. + editor_buffer.editor_content.maybe_file_extension = + Some(file_utils::get_file_extension(&Some( + user_input_file_path.clone(), + ))); + + // Fire a signal to save the file. + send_signal!( + main_thread_channel_sender, + TerminalWindowMainThreadSignal::ApplyAction( + AppSignal::SaveFile + ) + ); } } } @@ -591,36 +585,36 @@ mod populate_component_registry { mod stylesheet { use super::*; - pub fn create_stylesheet() -> CommonResult { + pub fn create_stylesheet() -> CommonResult { throws_with_return!({ - stylesheet! { - style! { + tui_stylesheet! { + tui_style! { id: Id::StyleEditorDefault.into() padding: 1 // These are ignored due to syntax highlighting. // attrib: [bold] // color_fg: TuiColor::Blue }, - style! { + tui_style! { id: Id::StyleDialogTitle.into() lolcat: true // These are ignored due to lolcat: true. // attrib: [bold] // color_fg: TuiColor::Yellow }, - style! { + tui_style! { id: Id::StyleDialogBorder.into() lolcat: true // These are ignored due to lolcat: true. // attrib: [dim] // color_fg: TuiColor::Green }, - style! { + tui_style! { id: Id::StyleDialogEditor.into() attrib: [bold] color_fg: TuiColor::Basic(ANSIBasicColor::Magenta) }, - style! { + tui_style! { id: Id::StyleDialogResultsPanel.into() // attrib: [bold] color_fg: TuiColor::Basic(ANSIBasicColor::Blue) @@ -635,7 +629,7 @@ mod status_bar { /// Shows helpful messages at the bottom row of the screen. pub fn render_status_bar(pipeline: &mut RenderPipeline, size: Size) { - let separator_style = style!( + let separator_style = tui_style!( attrib: [dim] color_fg: TuiColor::Basic(ANSIBasicColor::DarkGrey) ); @@ -660,18 +654,18 @@ mod status_bar { TextColorizationPolicy::ColorEachCharacter(None), ); - let styled_texts: StyledTexts = { + let styled_texts: TuiStyledTexts = { let mut it = Default::default(); it += app_text_styled_texts; - it += styled_text! { @style: separator_style , @text: " │ "}; - it += styled_text! { @style: style!(attrib: [dim]) , @text: "Save: Ctrl+S "}; - it += styled_text! { @style: style!() , @text: "💾"}; - it += styled_text! { @style: separator_style , @text: " │ "}; - it += styled_text! { @style: style!(attrib: [dim]) , @text: "Feedback: Ctrl+K "}; - it += styled_text! { @style: style!() , @text: "💭"}; - it += styled_text! { @style: separator_style , @text: " │ "}; - it += styled_text! { @style: style!(attrib: [dim]) , @text: "Exit: Ctrl+Q "}; - it += styled_text! { @style: style!() , @text: "🖖"}; + it += tui_styled_text! { @style: separator_style , @text: " │ "}; + it += tui_styled_text! { @style: tui_style!(attrib: [dim]) , @text: "Save: Ctrl+S "}; + it += tui_styled_text! { @style: tui_style!() , @text: "💾"}; + it += tui_styled_text! { @style: separator_style , @text: " │ "}; + it += tui_styled_text! { @style: tui_style!(attrib: [dim]) , @text: "Feedback: Ctrl+K "}; + it += tui_styled_text! { @style: tui_style!() , @text: "💭"}; + it += tui_styled_text! { @style: separator_style , @text: " │ "}; + it += tui_styled_text! { @style: tui_style!(attrib: [dim]) , @text: "Exit: Ctrl+Q "}; + it += tui_styled_text! { @style: tui_style!() , @text: "🖖"}; it }; diff --git a/cmdr/src/edi/state.rs b/cmdr/src/edi/state.rs index eddc29f3..58aac363 100644 --- a/cmdr/src/edi/state.rs +++ b/cmdr/src/edi/state.rs @@ -113,12 +113,9 @@ mod state_tests { // Check the state. assert_eq!(state.editor_buffers.len(), 1); assert_eq!(state.dialog_buffers.len(), 0); - assert_eq!( - state - .editor_buffers - .contains_key(&FlexBoxId::from(Id::ComponentEditor)), - true - ); + assert!(state + .editor_buffers + .contains_key(&FlexBoxId::from(Id::ComponentEditor))); assert_eq!( state .editor_buffers @@ -163,7 +160,7 @@ pub mod constructor { pub fn new(maybe_file_path: &Option) -> State { match maybe_file_path { Some(_) => State { - editor_buffers: create_hash_map_of_editor_buffers(&maybe_file_path), + editor_buffers: create_hash_map_of_editor_buffers(maybe_file_path), dialog_buffers: Default::default(), }, None => State::default(), @@ -175,20 +172,18 @@ pub mod constructor { ) -> HashMap { let editor_buffer = { let mut editor_buffer = EditorBuffer::new_empty( - &Some(file_utils::get_file_extension(&maybe_file_path)), + &Some(file_utils::get_file_extension(maybe_file_path)), maybe_file_path, ); - editor_buffer.set_lines(file_utils::get_content(&maybe_file_path)); + editor_buffer.set_lines(file_utils::get_content(maybe_file_path)); editor_buffer }; - let hash_map = { + { let mut it = HashMap::new(); it.insert(FlexBoxId::from(Id::ComponentEditor), editor_buffer); it - }; - - hash_map + } } } @@ -211,7 +206,7 @@ pub mod file_utils { } } - return DEFAULT_SYN_HI_FILE_EXT.to_owned(); + DEFAULT_SYN_HI_FILE_EXT.to_owned() } pub fn get_content(maybe_file_path: &Option) -> Vec { diff --git a/cmdr/src/giti/branch/checkout.rs b/cmdr/src/giti/branch/checkout.rs index dd74b10d..69dde888 100644 --- a/cmdr/src/giti/branch/checkout.rs +++ b/cmdr/src/giti/branch/checkout.rs @@ -35,7 +35,7 @@ use crate::{color_constants::DefaultColors::{FrozenBlue, NightBlue, Orange, SlateGray}, - giti::{clap_config::clap_config::BranchSubcommand, + giti::{clap_config::BranchSubcommand, report_unknown_error_and_propagate, single_select_instruction_header, ui_strings::UIStrings::*, @@ -99,7 +99,7 @@ pub fn try_checkout_branch( get_formatted_modified_files(output); // If user has files that are modified (unstaged or staged), but not committed. - if modified_files.len() > 0 { + if !modified_files.is_empty() { let terminal_width = get_terminal_width(); let one_modified_file = &ModifiedFileOnCurrentBranch.to_string(); @@ -287,7 +287,7 @@ pub fn try_checkout_branch( } } - return Ok(try_run_command_result); + Ok(try_run_command_result) } mod branch_checkout_formatting { @@ -305,11 +305,11 @@ mod branch_checkout_formatting { let mut modified_files_vec: Vec = Vec::new(); let modified_files = String::from_utf8_lossy(&output.stdout).to_string(); // Early return if there are no modified files. - if modified_files.len() == 0 { + if modified_files.is_empty() { return modified_files_vec; } let modified_files = modified_files.trim(); - let modified_files_vector: Vec<&str> = modified_files.split("\n").collect(); + let modified_files_vector: Vec<&str> = modified_files.split('\n').collect(); // Remove all the spaces from start and end of each modified file. let modified_files_vector: Vec = modified_files_vector .iter() diff --git a/cmdr/src/giti/branch/delete.rs b/cmdr/src/giti/branch/delete.rs index 7b07718a..90b180ee 100644 --- a/cmdr/src/giti/branch/delete.rs +++ b/cmdr/src/giti/branch/delete.rs @@ -27,7 +27,7 @@ use crate::{color_constants::DefaultColors::{FrozenBlue, LizardGreen, MoonlightBlue, SlateGray}, - giti::{clap_config::clap_config::BranchSubcommand, + giti::{clap_config::BranchSubcommand, giti_ui_templates::report_unknown_error_and_propagate, multi_select_instruction_header, single_select_instruction_header, @@ -263,7 +263,7 @@ mod try_delete_branch_inner { command } - pub fn display_one_branch_deleted_success_message(branches: &Vec) { + pub fn display_one_branch_deleted_success_message(branches: &[String]) { let lizard_green = LizardGreen.as_ansi_color(); let branch_name = &branches[0].to_string(); let deleted_branch = AnsiStyledText { @@ -328,11 +328,10 @@ pub fn get_branches() -> CommonResult> { let current_branch_result_output = show_current_branch_command.output(); - let current_branch; - match current_branch_result_output { + let current_branch = match current_branch_result_output { Ok(output) => { let output_string = String::from_utf8_lossy(&output.stdout); - current_branch = output_string.to_string().trim_end_matches('\n').to_string(); + output_string.to_string().trim_end_matches('\n').to_string() } // Can't even execute output(), something unknown has gone wrong. Propagate the // error. @@ -364,8 +363,7 @@ pub fn try_get_current_branch() -> CommonResult { let result_output = command.output(); - let current_branch; - match result_output { + let current_branch = match result_output { // Can't even execute output(), something unknown has gone wrong. Propagate the // error. Err(error) => { @@ -373,8 +371,9 @@ pub fn try_get_current_branch() -> CommonResult { } Ok(output) => { let output_string = String::from_utf8_lossy(&output.stdout); - current_branch = output_string.to_string().trim_end_matches('\n').to_string(); + output_string.to_string().trim_end_matches('\n').to_string() } }; + Ok(current_branch) } diff --git a/cmdr/src/giti/branch/giti_ui_templates.rs b/cmdr/src/giti/branch/giti_ui_templates.rs index e9919650..8610fcb2 100644 --- a/cmdr/src/giti/branch/giti_ui_templates.rs +++ b/cmdr/src/giti/branch/giti_ui_templates.rs @@ -100,13 +100,11 @@ pub fn show_exit_message() { "Run `cargo install r3bl-cmdr` to upgrade 🙌." ); - let lolcat_exit_msg = ColorWheel::default().colorize_into_string( + ColorWheel::default().colorize_into_string( &UnicodeString::from(plain_text_exit_msg), GradientGenerationPolicy::ReuseExistingGradientAndResetIndex, TextColorizationPolicy::ColorEachCharacter(None), - ); - - lolcat_exit_msg + ) }); } else { println!("{}", { diff --git a/cmdr/src/giti/branch/new.rs b/cmdr/src/giti/branch/new.rs index 45f84ac0..5c18d2da 100644 --- a/cmdr/src/giti/branch/new.rs +++ b/cmdr/src/giti/branch/new.rs @@ -27,7 +27,7 @@ use crate::{color_constants::DefaultColors::{FrozenBlue, SilverMetallic, SlateGray}, giti::{self, - clap_config::clap_config::BranchSubcommand, + clap_config::BranchSubcommand, report_unknown_error_and_propagate, CommandSuccessfulResponse, UIStrings::*}}; diff --git a/cmdr/src/giti/clap_config.rs b/cmdr/src/giti/clap_config.rs index 0bd379b5..7395e7e4 100644 --- a/cmdr/src/giti/clap_config.rs +++ b/cmdr/src/giti/clap_config.rs @@ -16,102 +16,93 @@ */ use clap::{Args, Parser, Subcommand, ValueEnum}; -use clap_config::*; pub fn get_giti_command_subcommand_names(arg: CLICommand) -> Vec { match arg { CLICommand::Branch { .. } => BranchSubcommand::value_variants() .iter() - .map(|subcommand| { - let lower_case_subcommand = - format!("{:?}", subcommand).to_ascii_lowercase(); - lower_case_subcommand - }) + .map(|subcommand| format!("{:?}", subcommand).to_ascii_lowercase()) .collect(), _ => unimplemented!(), } } +#[derive(Debug, Parser)] +#[command(bin_name = "giti")] +#[command( + about = "😺 Version control with confidence 💪\n\x1b[38;5;206mEarly access preview \x1b[0m🐣" +)] +#[command(version)] +#[command(next_line_help = true)] +#[command(arg_required_else_help(true))] +/// More info: +#[command( + help_template = "{about}\nVersion: {bin} {version} 💻\n\nUSAGE 📓:\n giti [\x1b[32mCommand\x1b[0m] [\x1b[34mOptions\x1b[0m]\n\n{all-args}\n", + subcommand_help_heading("Command") +)] + /// More info: /// - /// - -pub mod clap_config { - use super::*; - - #[derive(Debug, Parser)] - #[command(bin_name = "giti")] - #[command( - about = "😺 Version control with confidence 💪\n\x1b[38;5;206mEarly access preview \x1b[0m🐣" - )] - #[command(version)] - #[command(next_line_help = true)] - #[command(arg_required_else_help(true))] - /// More info: - #[command( - help_template = "{about}\nVersion: {bin} {version} 💻\n\nUSAGE 📓:\n giti [\x1b[32mCommand\x1b[0m] [\x1b[34mOptions\x1b[0m]\n\n{all-args}\n", - subcommand_help_heading("Command") - )] +pub struct CLIArg { + #[command(subcommand)] + pub command: CLICommand, - pub struct CLIArg { - #[command(subcommand)] - pub command: CLICommand, - - #[command(flatten)] - pub global_options: GlobalOption, - } + #[command(flatten)] + pub global_options: GlobalOption, +} - #[derive(Debug, Args)] - pub struct GlobalOption { - #[arg( - global = true, - long, - short = 'l', - help = "Log app output to a file named `log.txt` for debugging" - )] - pub enable_logging: bool, +#[derive(Debug, Args)] +pub struct GlobalOption { + #[arg( + global = true, + long, + short = 'l', + help = "Log app output to a file named `log.txt` for debugging" + )] + pub enable_logging: bool, - #[arg( - global = true, - long, - short = 'n', - help = "Disable anonymous data collection for analytics to improve the product; this data does not include IP addresses, or any other private user data, like user, branch, or repo names" - )] - pub no_analytics: bool, - } + #[arg( + global = true, + long, + short = 'n', + help = "Disable anonymous data collection for analytics to improve the product; this data does not include IP addresses, or any other private user data, like user, branch, or repo names" + )] + pub no_analytics: bool, +} - #[derive(Debug, Subcommand)] - pub enum CLICommand { - #[clap( - about = "🌱 Manage your git branches with commands: `delete`, `checkout`, and `new`\n💡 Eg: `giti branch delete`" - )] - /// More info: - #[command( +#[derive(Debug, Subcommand)] +pub enum CLICommand { + #[clap( + about = "🌱 Manage your git branches with commands: `delete`, `checkout`, and `new`\n💡 Eg: `giti branch delete`" + )] + /// More info: + #[command( /* cSpell:disable-next-line */ help_template = "{about} \n\nUSAGE 📓:\n giti branch [\x1b[34mcommand\x1b[0m] [\x1b[32moptions\x1b[0m]\n\n{positionals}\n\n [options]\n{options}" )] - Branch { - #[arg( - value_name = "command", - help = "In your shell, this command will execute, taking each selected item as an argument." - )] - command_to_run_with_each_selection: Option, - maybe_branch_name: Option, - }, + Branch { + #[arg( + value_name = "command", + help = "In your shell, this command will execute, taking each selected item as an argument." + )] + command_to_run_with_each_selection: Option, + maybe_branch_name: Option, + }, - #[clap(about = "TODO Commit help")] - Commit {}, + #[clap(about = "TODO Commit help")] + Commit {}, - #[clap(about = "TODO Remote help")] - Remote {}, - } + #[clap(about = "TODO Remote help")] + Remote {}, +} - #[derive(Clone, Debug, ValueEnum)] - pub enum BranchSubcommand { - #[clap(help = "Delete one or more selected branches")] - Delete, - #[clap(help = "Switch to the selected branch")] - Checkout, - #[clap(help = "TODO Create a new branch")] - New, - } +#[derive(Clone, Debug, ValueEnum)] +pub enum BranchSubcommand { + #[clap(help = "Delete one or more selected branches")] + Delete, + #[clap(help = "Switch to the selected branch")] + Checkout, + #[clap(help = "TODO Create a new branch")] + New, } diff --git a/cmdr/src/giti/common_types.rs b/cmdr/src/giti/common_types.rs index e8876e32..b28036d8 100644 --- a/cmdr/src/giti/common_types.rs +++ b/cmdr/src/giti/common_types.rs @@ -15,7 +15,7 @@ * limitations under the License. */ -use super::clap_config::clap_config::BranchSubcommand; +use super::clap_config::BranchSubcommand; #[derive(Debug, Clone, Default)] pub struct CommandSuccessfulResponse { diff --git a/cmdr/src/giti/ui_strings.rs b/cmdr/src/giti/ui_strings.rs index c927e3e0..c0c91a5f 100644 --- a/cmdr/src/giti/ui_strings.rs +++ b/cmdr/src/giti/ui_strings.rs @@ -15,6 +15,8 @@ * limitations under the License. */ +use std::fmt::{Display, Formatter}; + pub enum UIStrings { PleaseSelectBranchesYouWantToDelete, ConfirmDeletingOneBranch { @@ -85,134 +87,135 @@ pub enum UIStrings { NoNewBranchWasCreated, } -impl UIStrings { - pub fn to_string(&self) -> String { - match self { - UIStrings::PleaseSelectBranchesYouWantToDelete => { - String::from(" Please select branches you want to delete") - } - UIStrings::ConfirmDeletingOneBranch { branch_name } => { - format!(" Confirm deleting 1 branch: {branch_name}") - } - UIStrings::ConfirmDeletingMultipleBranches { - num_of_branches, - branches_to_delete, - } => { - format!( - " Confirm deleting {} branches: {}?", - num_of_branches, branches_to_delete - ) - } - UIStrings::YesDeleteBranch => String::from("Yes, delete branch"), - UIStrings::YesDeleteBranches => String::from("Yes, delete branches"), - UIStrings::Exit => String::from("Exit"), - UIStrings::FailedToDeleteBranch { - branch_name, - error_message, - } => { - format!( - " Failed to delete branch: {}!\n\n{}", - branch_name, error_message - ) - } - UIStrings::FailedToDeleteBranches { - branches, - error_message, - } => { - format!( - " Failed to delete branches:\n ╴{}!\n\n{}", - branches, error_message - ) - } - UIStrings::FailedToRunCommandToDeleteBranches { branches } => { - format!(" Failed to run command to delete branches:\n ╴{branches}!") - } - UIStrings::Deleted => String::from("deleted"), - UIStrings::CurrentBranch { branch } => { - format!("(current) {branch}") - } - UIStrings::SelectBranchToSwitchTo => { - String::from(" Select a branch to switch to") - } - UIStrings::AlreadyOnCurrentBranch => { - String::from(" You are already on branch ") - } - UIStrings::SwitchedToBranch => String::from(" Switched to branch ✅ "), - UIStrings::FailedToSwitchToBranch { - branch, - error_message, - } => { - format!( - " Failed to switch to branch '{branch}'!\n\n{}", - error_message - ) - } - UIStrings::NoBranchGotCheckedOut { branch } => { - format!(" No branch got checked out ... \n ╴{branch}!\n\n") - } - UIStrings::GoodbyeThanksForUsingGitiUsername { username } => { - format!("\n Goodbye, 👋 {}. Thanks for using 😺 giti!", username) - } - UIStrings::GoodbyeThanksForUsingGiti => { - format!( - "\n Goodbye 👋. - - 😺 giti!" - ) - } - UIStrings::PleaseStarUs => { - format!( - "{}: {}", - " Please star us and report issues on GitHub", - "🌟 🐞 https://github.com/r3bl-org/r3bl-open-core/issues/new/choose" - ) - } - UIStrings::ErrorExecutingCommand { - program_name_to_string, - command_args_to_string, - command_output_error, - } => { - format!( - " Error executing command: '{program_name_to_string} {command_args_to_string}'. Error: {command_output_error}" - ) - } - UIStrings::BranchDoesNotExist { branch_name } => { - format!("Branch `{}` does not exist.", branch_name) - } - UIStrings::ModifiedFileOnCurrentBranch => { - format!(" You have a 📝 modified file on the current branch: ") - } - UIStrings::ModifiedFilesOnCurrentBranch => { - format!(" You have 📝 modified files on the current branch: ") - } - UIStrings::WouldYouLikeToSwitchToBranch { branch_name } => { - format!(" Would you like to switch to branch '{branch_name}?'") - } - UIStrings::SwitchToBranchAndApplyChanges => { - String::from("Switch to branch and apply changes") - } - UIStrings::StayOnCurrentBranch => String::from("Stay on current branch"), - UIStrings::StayingOnCurrentBranch => { - String::from(" Staying on current branch ") - } - UIStrings::PleaseCommitChangesBeforeSwitchingBranches => String::from( - " Please commit your changes or stash them before you switch branches.", - ), - UIStrings::BranchAlreadyExists { branch_name } => { - format!(" Branch {branch_name} already exists!") - } - UIStrings::CreatedAndSwitchedToNewBranch => { - format!(" You created and switched to branch ") - } - UIStrings::FailedToCreateAndSwitchToBranch { branch_name } => { - format!(" Failed to create and switch to branch {branch_name}") - } - UIStrings::EnterBranchNameYouWantToCreate => { - format!(" Enter a branch name you want to create (Ctrl+C to exit) ") - } - UIStrings::NoNewBranchWasCreated => { - String::from(" No new branch was created") +impl Display for UIStrings { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + fn to_string(this: &UIStrings) -> String { + match this { + UIStrings::PleaseSelectBranchesYouWantToDelete => { + String::from(" Please select branches you want to delete") + } + UIStrings::ConfirmDeletingOneBranch { branch_name } => { + format!(" Confirm deleting 1 branch: {branch_name}") + } + UIStrings::ConfirmDeletingMultipleBranches { + num_of_branches, + branches_to_delete, + } => { + format!( + " Confirm deleting {} branches: {}?", + num_of_branches, branches_to_delete + ) + } + UIStrings::YesDeleteBranch => String::from("Yes, delete branch"), + UIStrings::YesDeleteBranches => String::from("Yes, delete branches"), + UIStrings::Exit => String::from("Exit"), + UIStrings::FailedToDeleteBranch { + branch_name, + error_message, + } => { + format!( + " Failed to delete branch: {}!\n\n{}", + branch_name, error_message + ) + } + UIStrings::FailedToDeleteBranches { + branches, + error_message, + } => { + format!( + " Failed to delete branches:\n ╴{}!\n\n{}", + branches, error_message + ) + } + UIStrings::FailedToRunCommandToDeleteBranches { branches } => { + format!(" Failed to run command to delete branches:\n ╴{branches}!") + } + UIStrings::Deleted => String::from("deleted"), + UIStrings::CurrentBranch { branch } => { + format!("(current) {branch}") + } + UIStrings::SelectBranchToSwitchTo => { + String::from(" Select a branch to switch to") + } + UIStrings::AlreadyOnCurrentBranch => { + String::from(" You are already on branch ") + } + UIStrings::SwitchedToBranch => String::from(" Switched to branch ✅ "), + UIStrings::FailedToSwitchToBranch { + branch, + error_message, + } => { + format!( + " Failed to switch to branch '{branch}'!\n\n{}", + error_message + ) + } + UIStrings::NoBranchGotCheckedOut { branch } => { + format!(" No branch got checked out ... \n ╴{branch}!\n\n") + } + UIStrings::GoodbyeThanksForUsingGitiUsername { username } => { + format!("\n Goodbye, 👋 {}. Thanks for using 😺 giti!", username) + } + UIStrings::GoodbyeThanksForUsingGiti => "\n Goodbye 👋. + + 😺 giti!" + .to_string(), + UIStrings::PleaseStarUs => { + format!( + "{}: {}", + " Please star us and report issues on GitHub", + "🌟 🐞 https://github.com/r3bl-org/r3bl-open-core/issues/new/choose" + ) + } + UIStrings::ErrorExecutingCommand { + program_name_to_string, + command_args_to_string, + command_output_error, + } => { + format!( + " Error executing command: '{program_name_to_string} {command_args_to_string}'. Error: {command_output_error}" + ) + } + UIStrings::BranchDoesNotExist { branch_name } => { + format!("Branch `{}` does not exist.", branch_name) + } + UIStrings::ModifiedFileOnCurrentBranch => { + " You have a 📝 modified file on the current branch: ".to_string() + } + UIStrings::ModifiedFilesOnCurrentBranch => { + " You have 📝 modified files on the current branch: ".to_string() + } + UIStrings::WouldYouLikeToSwitchToBranch { branch_name } => { + format!(" Would you like to switch to branch '{branch_name}?'") + } + UIStrings::SwitchToBranchAndApplyChanges => { + String::from("Switch to branch and apply changes") + } + UIStrings::StayOnCurrentBranch => String::from("Stay on current branch"), + UIStrings::StayingOnCurrentBranch => { + String::from(" Staying on current branch ") + } + UIStrings::PleaseCommitChangesBeforeSwitchingBranches => String::from( + " Please commit your changes or stash them before you switch branches.", + ), + UIStrings::BranchAlreadyExists { branch_name } => { + format!(" Branch {branch_name} already exists!") + } + UIStrings::CreatedAndSwitchedToNewBranch => { + " You created and switched to branch ".to_string() + } + UIStrings::FailedToCreateAndSwitchToBranch { branch_name } => { + format!(" Failed to create and switch to branch {branch_name}") + } + UIStrings::EnterBranchNameYouWantToCreate => { + " Enter a branch name you want to create (Ctrl+C to exit) ".to_string() + } + UIStrings::NoNewBranchWasCreated => { + String::from(" No new branch was created") + } } } + + write!(f, "{}", to_string(self)) } } diff --git a/cmdr/src/lib.rs b/cmdr/src/lib.rs index 5d2e6119..f3019f2c 100644 --- a/cmdr/src/lib.rs +++ b/cmdr/src/lib.rs @@ -176,6 +176,7 @@ #![warn(rust_2018_idioms)] pub const DEVELOPMENT_MODE: bool = true; +pub const DEBUG_ANALYTICS_CLIENT_MOD: bool = true; // Attach sources. pub mod analytics_client; diff --git a/core/Cargo.toml b/core/Cargo.toml index 0c8be336..3d68eab3 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -46,9 +46,6 @@ get-size = { version = "0.1.4", features = ["derive"] } chrono = "0.4.31" time = "0.3.30" -# Syntax highlighting. -syntect = "5.1.0" - # nom parser combinator. nom = "7.1.3" diff --git a/core/src/tui_core/dimens/ch_unit.rs b/core/src/tui_core/dimens/ch_unit.rs index 254e6914..900fa65a 100644 --- a/core/src/tui_core/dimens/ch_unit.rs +++ b/core/src/tui_core/dimens/ch_unit.rs @@ -257,11 +257,7 @@ pub mod convert_from_number { } impl From for ChUnit { - fn from(value: u8) -> Self { - Self { - value: value.try_into().unwrap_or(value as ChUnitPrimitiveType), - } - } + fn from(it: u8) -> Self { Self { value: it.into() } } } impl From for ChUnit { diff --git a/core/src/tui_core/graphemes/range.rs b/core/src/tui_core/graphemes/range.rs index 32d1efe5..a5d87e52 100644 --- a/core/src/tui_core/graphemes/range.rs +++ b/core/src/tui_core/graphemes/range.rs @@ -15,7 +15,7 @@ * limitations under the License. */ -use std::{cmp::{self, Ord}, +use std::{cmp::{self}, fmt::{Debug, Display}}; use get_size::GetSize; diff --git a/core/src/tui_core/graphemes/test_unicode_string.rs b/core/src/tui_core/graphemes/test_unicode_string.rs index 11d53a97..4c272b28 100644 --- a/core/src/tui_core/graphemes/test_unicode_string.rs +++ b/core/src/tui_core/graphemes/test_unicode_string.rs @@ -276,7 +276,7 @@ mod tests { assert_eq2! {lhs_u_s.truncate_start_by_n_col(00.into()), "Hi "}; assert_eq2! {rhs_u_s.truncate_start_by_n_col(00.into()), "😃 📦 🙏🏽 👨🏾‍🤝‍👨🏿."}; - let acc = vec![lhs_u_s, rhs_u_s]; + let acc = [lhs_u_s, rhs_u_s]; assert_eq2! {acc[0].string, "Hi "}; assert_eq2! {acc[1].string, "😃 📦 🙏🏽 👨🏾‍🤝‍👨🏿."}; } diff --git a/core/src/tui_core/graphemes/unicode_string.rs b/core/src/tui_core/graphemes/unicode_string.rs index fd98cf46..3ce16e66 100644 --- a/core/src/tui_core/graphemes/unicode_string.rs +++ b/core/src/tui_core/graphemes/unicode_string.rs @@ -49,7 +49,7 @@ mod grapheme_cluster_segment_impl { pub fn new(chunk: &str) -> GraphemeClusterSegment { let my_string: String = chunk.to_string(); let unicode_string = UnicodeString::from(my_string); - let result = unicode_string.vec_segment.get(0).unwrap().clone(); + let result = unicode_string.vec_segment.first().unwrap().clone(); result } } diff --git a/core/src/tui_core/styles/mod.rs b/core/src/tui_core/styles/mod.rs index e630bbba..d99d3240 100644 --- a/core/src/tui_core/styles/mod.rs +++ b/core/src/tui_core/styles/mod.rs @@ -17,12 +17,12 @@ // Attach sources. pub mod hex_color_parser; -pub mod style; -pub mod stylesheet; pub mod tui_color; +pub mod tui_style; +pub mod tui_stylesheet; // Re-export. pub use hex_color_parser::*; -pub use style::*; -pub use stylesheet::*; pub use tui_color::*; +pub use tui_style::*; +pub use tui_stylesheet::*; diff --git a/core/src/tui_core/styles/style.rs b/core/src/tui_core/styles/tui_style.rs similarity index 78% rename from core/src/tui_core/styles/style.rs rename to core/src/tui_core/styles/tui_style.rs index 2b76b07d..0dd0b740 100644 --- a/core/src/tui_core/styles/style.rs +++ b/core/src/tui_core/styles/tui_style.rs @@ -24,42 +24,44 @@ use serde::{Deserialize, Serialize}; use crate::*; -/// Please use [style!](crate::style) proc macro to generate code for this struct. For the macro, if +/// Please use [tui_style!](crate::tui_style) proc macro to generate code for this struct. For the macro, if /// `id` isn't supplied, then [u8::MAX](u8::MAX) is used. This represents the "style does not have /// an assigned id" case. Computed styles don't have an id and are set to [u8::MAX](u8::MAX) as /// well. /// /// Here's an example. /// -/// ```ignore -/// use r3bl_rs_utils_core::Stylesheet; -/// use r3bl_rs_utils_macro::style; +/// ```rust +/// use r3bl_rs_utils_core::{TuiStyle, TuiColor, TuiStylesheet, RgbValue}; /// /// // Turquoise: TuiColor::Rgb { r: 51, g: 255, b: 255 } /// // Pink: TuiColor::Rgb { r: 252, g: 157, b: 248 } /// // Blue: TuiColor::Rgb { r: 55, g: 55, b: 248 } /// // Faded blue: TuiColor::Rgb { r: 85, g: 85, b: 255 } -/// let mut stylesheet = Stylesheet::new(); +/// let mut stylesheet = TuiStylesheet::new(); /// -/// stylesheet.add_styles(vec![ -/// style! { -/// id: style1 -/// attrib: [dim, bold] -/// padding: 1 -/// color_bg: TuiColor::Rgb { r: 55, g: 55, b: 248 } -/// }, -/// style! { -/// id: style2 -/// padding: 1 -/// color_bg: TuiColor::Rgb { r: 85, g: 85, b: 255 } -/// } +/// let _ = stylesheet.add_styles(vec![ +/// TuiStyle { +/// id: 1, +/// bold: true, +/// dim: true, +/// color_fg: Some(TuiColor::Rgb (RgbValue{ red: 55, green: 55, blue: 248 })), +/// .. Default::default() +/// }, +/// TuiStyle { +/// id: 1, +/// bold: true, +/// dim: true, +/// color_fg: Some(TuiColor::Rgb (RgbValue{ red: 55, green: 55, blue: 248 })), +/// .. Default::default() +/// }, /// ]); /// ``` /// /// Here are the [crossterm docs on /// attributes](https://docs.rs/crossterm/0.25.0/crossterm/style/enum.Attribute.html) #[derive(Copy, Default, Clone, PartialEq, Eq, Serialize, Deserialize, Hash, GetSize)] -pub struct Style { +pub struct TuiStyle { pub id: u8, pub bold: bool, pub italic: bool, @@ -83,24 +85,24 @@ pub struct Style { mod addition { use super::*; - impl Add for Style { + impl Add for TuiStyle { type Output = Self; fn add(self, other: Self) -> Self { add_styles(self, other) } } - pub fn add_styles(lhs: Style, rhs: Style) -> Style { + pub fn add_styles(lhs: TuiStyle, rhs: TuiStyle) -> TuiStyle { // Computed style has no id. - let mut new_style: Style = Style { + let mut new_style: TuiStyle = TuiStyle { id: u8::MAX, computed: true, - ..Style::default() + ..TuiStyle::default() }; apply_style_flag(&mut new_style, &lhs); apply_style_flag(&mut new_style, &rhs); // other (if set) overrides new_style. - fn apply_style_flag(new_style: &mut Style, other: &Style) { + fn apply_style_flag(new_style: &mut TuiStyle, other: &TuiStyle) { if other.color_fg.is_some() { new_style.color_fg = other.color_fg; } @@ -145,22 +147,22 @@ mod addition { new_style } - impl AddAssign