From 2e6320185ba358368506fd8b8f2fdae9763447b0 Mon Sep 17 00:00:00 2001 From: Namilskyy Date: Sat, 22 Nov 2025 22:17:43 +0300 Subject: Fixed tearing in output --- src/main.rs | 19 ++++++++++++++----- src/parser.rs | 36 ++++++++++++++++++++++++++++++++++-- 2 files changed, 48 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/main.rs b/src/main.rs index 308e6db..615ed4a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -39,7 +39,13 @@ use clap::{Parser, Subcommand}; mod parser; mod shared; -use parser::{generate_config, get_config, parse_weather, Config}; +use parser::{generate_config, + get_config, + parse_weather, + Config, + visible_length, + pad_with_ansi}; + use shared::WeatherData; use crate::parser::{determine_weather_type, prepare_art}; @@ -216,7 +222,7 @@ fn main() -> Result<(), Box> { let art_lines: Vec<&str> = art_string.lines().collect(); - let max_art_width = art_lines.iter().map(|line| line.len()).max().unwrap_or(0); + let max_art_width = art_lines.iter().map(|line| visible_length(line)).max().unwrap_or(0); let max_lines = art_lines.len().max(table_lines.len()); @@ -224,8 +230,10 @@ fn main() -> Result<(), Box> { let art_part = art_lines.get(i).unwrap_or(&""); let table_part = table_lines.get(i).map(|s| s.as_str()).unwrap_or(""); - println!("{: { @@ -239,7 +247,7 @@ fn main() -> Result<(), Box> { let art_lines: Vec<&str> = art_string.lines().collect(); - let max_art_width = art_lines.iter().map(|line| line.len()).max().unwrap_or(0); + let max_art_width = art_lines.iter().map(|line| visible_length(line)).max().unwrap_or(0); let max_lines = art_lines.len().max(table_lines.len()); @@ -247,7 +255,8 @@ fn main() -> Result<(), Box> { let art_part = art_lines.get(i).unwrap_or(&""); let table_part = table_lines.get(i).map(|s| s.as_str()).unwrap_or(""); - println!("{: Result> { fn process_placeholders(art: &str) -> String { let strart = art.to_string(); - let mut processed_art = strart.replace("{0}", " ") + let processed_art = strart.replace("{0}", " ") .replace("", "\x1b[0;33m") .replace("", "\x1b[0;34m") .replace("", "\x1b[0;35m") @@ -206,3 +206,35 @@ pub fn prepare_art(weather_data: &WeatherData, debug: bool) -> Result usize { + let mut count = 0; + let mut chars = s.chars().peekable(); + + while let Some(ch) = chars.next() { + if ch == '\x1b' && chars.peek() == Some(&'[') { + // Found ANSI escape sequence, skip until 'm' + chars.next(); // consume '[' + while let Some(&next_ch) = chars.peek() { + chars.next(); // consume character + if next_ch == 'm' { + break; // end of ANSI sequence + } + } + } else { + count += 1; + } + } + + count +} + + +/// Left-pad a string with spaces to the specified visible width, accounting for ANSI codes +pub fn pad_with_ansi(s: &str, width: usize) -> String { + let visible_len = visible_length(s); + let padding_needed = if width > visible_len { width - visible_len } else { 0 }; + let padding = " ".repeat(padding_needed); + format!("{}{}", s, padding) +} \ No newline at end of file -- cgit v1.2.3