summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/main.rs19
-rw-r--r--src/parser.rs36
2 files changed, 48 insertions, 7 deletions
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<dyn std::error::Error>> {
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<dyn std::error::Error>> {
let art_part = art_lines.get(i).unwrap_or(&"");
let table_part = table_lines.get(i).map(|s| s.as_str()).unwrap_or("");
- println!("{:<width$} {}", art_part, table_part, width = max_art_width);
+ let padded_art = pad_with_ansi(art_part, max_art_width);
+ println!("{} {}", padded_art, table_part);
}
+
Ok(())
}
Some(Commands::Tomorrow) => {
@@ -239,7 +247,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
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<dyn std::error::Error>> {
let art_part = art_lines.get(i).unwrap_or(&"");
let table_part = table_lines.get(i).map(|s| s.as_str()).unwrap_or("");
- println!("{:<width$} {}", art_part, table_part, width = max_art_width);
+ let padded_art = pad_with_ansi(art_part, max_art_width);
+ println!("{} {}", padded_art, table_part);
}
Ok(())
}
diff --git a/src/parser.rs b/src/parser.rs
index 8e17682..8def9c2 100644
--- a/src/parser.rs
+++ b/src/parser.rs
@@ -7,7 +7,7 @@ use reqwest::Client;
use toml;
use serde::{Deserialize, Serialize};
use serde_json;
-use serde_yml;
+use serde_yml;
// use crate::configmanager::Config;
use crate::shared::*;
@@ -162,7 +162,7 @@ fn load_arts(debug: bool) -> Result<ArtsData, Box<dyn std::error::Error>> {
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("<Yellow>", "\x1b[0;33m")
.replace("<Blue>", "\x1b[0;34m")
.replace("<Purple>", "\x1b[0;35m")
@@ -206,3 +206,35 @@ pub fn prepare_art(weather_data: &WeatherData, debug: bool) -> Result<String, Bo
}
Ok(processed_art)
}
+
+/// Remove ANSI escape codes from string and return visible length
+pub fn visible_length(s: &str) -> 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