Skip to main content

proc_cli/ui/
format.rs

1//! Shared formatting utilities used across commands and output
2//!
3//! Provides common string formatting, truncation, and colorization.
4
5use crate::core::ProcessStatus;
6use colored::*;
7
8/// Format a duration in seconds to a human-readable string.
9///
10/// Examples: "45s", "3m 12s", "2h 15m", "1d 6h"
11pub fn format_duration(secs: u64) -> String {
12    if secs < 60 {
13        format!("{}s", secs)
14    } else if secs < 3600 {
15        format!("{}m {}s", secs / 60, secs % 60)
16    } else if secs < 86400 {
17        format!("{}h {}m", secs / 3600, (secs % 3600) / 60)
18    } else {
19        format!("{}d {}h", secs / 86400, (secs % 86400) / 3600)
20    }
21}
22
23/// Truncate a string to a maximum length, appending "..." if truncated.
24pub fn truncate_string(s: &str, max_len: usize) -> String {
25    if s.len() <= max_len {
26        s.to_string()
27    } else {
28        format!("{}...", &s[..max_len.saturating_sub(3)])
29    }
30}
31
32/// Truncate a path intelligently — shows the end (most relevant part).
33pub fn truncate_path(path: &str, max_len: usize) -> String {
34    if path.len() <= max_len {
35        path.to_string()
36    } else {
37        let start = path.len().saturating_sub(max_len.saturating_sub(3));
38        format!("...{}", &path[start..])
39    }
40}
41
42/// Format memory in MB to a human-readable string with adaptive units.
43///
44/// Examples: "512KB", "6.0MB", "3.0GB"
45pub fn format_memory(memory_mb: f64) -> String {
46    if memory_mb < 1.0 {
47        format!("{:.0}KB", memory_mb * 1000.0)
48    } else if memory_mb < 1000.0 {
49        format!("{:.1}MB", memory_mb)
50    } else {
51        format!("{:.1}GB", memory_mb / 1000.0)
52    }
53}
54
55/// Colorize a process status string based on the status variant.
56pub fn colorize_status(status: &ProcessStatus, status_str: &str) -> ColoredString {
57    match status {
58        ProcessStatus::Running => status_str.green(),
59        ProcessStatus::Sleeping => status_str.blue(),
60        ProcessStatus::Stopped => status_str.yellow(),
61        ProcessStatus::Zombie => status_str.red(),
62        _ => status_str.white(),
63    }
64}