use std::io::Write;
use crossterm::{queue, style::Color, style::Print};
use crate::device::MemoryInfo;
use crate::ui::text::print_colored_text;
use crate::ui::widgets::{draw_bar_multi, BarSegment};
#[allow(dead_code)]
pub struct MemoryRenderer;
impl Default for MemoryRenderer {
fn default() -> Self {
Self::new()
}
}
#[allow(dead_code)]
impl MemoryRenderer {
pub fn new() -> Self {
Self
}
}
fn format_hostname_with_scroll(hostname: &str, scroll_offset: usize) -> String {
if hostname.len() > 9 {
let scroll_len = hostname.len() + 3;
let start_pos = scroll_offset % scroll_len;
let extended_hostname = format!("{hostname} {hostname}");
extended_hostname
.chars()
.skip(start_pos)
.take(9)
.collect::<String>()
} else {
format!("{hostname:<9}")
}
}
pub fn print_memory_info<W: Write>(
stdout: &mut W,
_index: usize,
info: &MemoryInfo,
width: usize,
hostname_scroll_offset: usize,
) {
let total_gb = info.total_bytes as f64 / (1024.0 * 1024.0 * 1024.0);
let used_gb = info.used_bytes as f64 / (1024.0 * 1024.0 * 1024.0);
let available_gb = info.available_bytes as f64 / (1024.0 * 1024.0 * 1024.0);
let hostname_display = format_hostname_with_scroll(&info.hostname, hostname_scroll_offset);
print_colored_text(stdout, "Host Memory ", Color::Cyan, None, None);
print_colored_text(stdout, " @ ", Color::DarkGreen, None, None);
print_colored_text(stdout, &hostname_display, Color::White, None, None);
print_colored_text(stdout, " Total:", Color::Green, None, None);
print_colored_text(
stdout,
&format!("{total_gb:>6.0}GB"),
Color::White,
None,
None,
);
print_colored_text(stdout, " Used:", Color::Red, None, None);
print_colored_text(
stdout,
&format!("{used_gb:>6.1}GB"),
Color::White,
None,
None,
);
print_colored_text(stdout, " Avail:", Color::Green, None, None);
print_colored_text(
stdout,
&format!("{available_gb:>6.1}GB"),
Color::White,
None,
None,
);
print_colored_text(stdout, " Util:", Color::Magenta, None, None);
print_colored_text(
stdout,
&format!("{:>5.1}%", info.utilization),
Color::White,
None,
None,
);
queue!(stdout, Print("\r\n")).unwrap();
let available_width = width.saturating_sub(10); let gauge_width = available_width;
let total_gauge_width = gauge_width;
let left_padding = 5;
let right_padding = width - left_padding - total_gauge_width;
print_colored_text(stdout, " ", Color::White, None, None);
let mut segments = Vec::new();
let actual_used_bytes = info
.used_bytes
.saturating_sub(info.buffers_bytes + info.cached_bytes);
let actual_used_gb = actual_used_bytes as f64 / (1024.0 * 1024.0 * 1024.0);
let buffers_gb = info.buffers_bytes as f64 / (1024.0 * 1024.0 * 1024.0);
let cached_gb = info.cached_bytes as f64 / (1024.0 * 1024.0 * 1024.0);
if actual_used_bytes > 0 {
segments.push(BarSegment::memory_used(actual_used_gb));
}
if info.buffers_bytes > 0 {
segments.push(BarSegment::memory_buffers(buffers_gb));
}
if info.cached_bytes > 0 {
segments.push(BarSegment::memory_cache(cached_gb));
}
let total_used_gb = actual_used_gb + buffers_gb + cached_gb;
let display_text = format!("{total_used_gb:.1}GB");
draw_bar_multi(
stdout,
"Mem",
&segments,
total_gb,
gauge_width,
Some(display_text),
);
print_colored_text(stdout, &" ".repeat(right_padding), Color::White, None, None);
queue!(stdout, Print("\r\n")).unwrap();
}