M4: fetch mode, cleanup and documentation

- --fetch with a Jinja-subset renderer and the shipped templates
- clippy clean, cargo fmt, all tests green
- README status and differential testing instructions
This commit is contained in:
glances-rs
2026-10-09 23:59:26 +00:00
parent cb22e53aa6
commit 6819ce4e18
47 changed files with 4145 additions and 935 deletions
+33 -11
View File
@@ -69,7 +69,22 @@ pub fn auto_unit(number: f64, low_precision: bool, min_symbol: &str, none_symbol
/// Render a progress bar the way the Python `Bar` class does.
pub fn bar_percent(percent: f64, size: usize, bar_char: &str, display_value: bool) -> String {
let size = if display_value { size.saturating_sub(6) } else { size };
bar_custom(percent, size, bar_char, " ", display_value)
}
/// Render a progress bar with custom characters.
pub fn bar_custom(
percent: f64,
size: usize,
bar_char: &str,
empty_char: &str,
display_value: bool,
) -> String {
let size = if display_value {
size.saturating_sub(6)
} else {
size
};
let value = percent.clamp(0.0, 100.0);
let scaled = size as f64 * value / 100.0;
let whole = scaled.floor() as usize;
@@ -81,14 +96,18 @@ pub fn bar_percent(percent: f64, size: usize, bar_char: &str, display_value: boo
if (frac * 8.0) as usize >= 5 {
bar.push_str(bar_char);
} else {
bar.push(' ');
bar.push_str(empty_char);
}
whole += 1;
}
bar.push_str(&" ".repeat(size.saturating_sub(whole)));
bar.push_str(&empty_char.repeat(size.saturating_sub(whole)));
if display_value {
if percent >= 100.0 {
bar = format!("{bar} {}{:3.0}%", if percent > 100.0 { ">" } else { " " }, 100.0);
bar = format!(
"{bar} {}{:3.0}%",
if percent > 100.0 { ">" } else { " " },
100.0
);
} else {
bar = format!("{bar}{percent:5.1}%");
}
@@ -104,11 +123,9 @@ pub fn string_value_to_float(s: &str) -> Option<f64> {
let mut digits = String::new();
let mut rest = String::new();
for c in cleaned.chars() {
if c.is_ascii_digit() || c == '.' {
if rest.is_empty() {
digits.push(c);
continue;
}
if (c.is_ascii_digit() || c == '.') && rest.is_empty() {
digits.push(c);
continue;
}
rest.push(c);
}
@@ -195,7 +212,9 @@ pub fn py_repr(value: &Value) -> String {
pub fn as_f64(value: &Value) -> Option<f64> {
match value {
Value::Number(n) => n.as_f64(),
Value::Bool(_) | Value::Null | Value::String(_) | Value::Array(_) | Value::Object(_) => None,
Value::Bool(_) | Value::Null | Value::String(_) | Value::Array(_) | Value::Object(_) => {
None
}
}
}
@@ -242,7 +261,10 @@ pub fn split_esc(input: &str, sep: char, esc: char) -> Vec<String> {
/// shell by adding a `$` prefix in front of them. (Only the replacement
/// flavour is needed by the plugins.)
pub fn replace_special_chars(input: &str, by: char) -> String {
input.replace("\r\n", &by.to_string()).replace('\n', &by.to_string()).replace('\t', &by.to_string())
input
.replace("\r\n", &by.to_string())
.replace('\n', &by.to_string())
.replace('\t', &by.to_string())
}
#[cfg(test)]