use anyhow::Result; use std::time::Duration; use m::vfd::VfdConfig; use m::worker::VfdWorker; fn pad_left(s: &str, width: usize) -> String { // простая подгонка ширины, чтобы при уменьшении числа не оставались “хвосты” if s.chars().count() >= width { s.chars().take(width).collect() } else { format!("{:>width$}", s, width = width) } } fn main() -> Result<()> { // args: // 1) port (default: /dev/cu.usbmodem101) // 2) width (default: 20) // 3) delay_ms (default: 200) let port_name = std::env::args() .nth(1) .unwrap_or("/dev/cu.usbmodem101".into()); let width: usize = std::env::args() .nth(2) .as_deref() .unwrap_or("20") .parse() .unwrap_or(20); let delay_ms: u64 = std::env::args() .nth(3) .as_deref() .unwrap_or("200") .parse() .unwrap_or(200); let cfg = VfdConfig::new(port_name).with_width(width); let worker = VfdWorker::start(cfg)?; let vfd = worker.handle(); vfd.clear(); // Рисуем “шаблон” один раз (как UI) // 12345678901234567890 // Temp: __.__C RPM:____ // Load: ___% Uptime:____ let _ = vfd.print_line_diff(1, "Temp: 00.00C RPM:0000"); let _ = vfd.print_line_diff(2, "Load: 000% Up:0000s"); // Координаты (1-based): // "Temp: 00.00C ..." -> числа начинаются с x=7, длина 5 (00.00) let temp_x = 7u8; let temp_w = 5usize; // "RPM:0000" -> числа начинаются после "RPM:"; в строке выше это x=16, длина 4 let rpm_x = 16u8; let rpm_w = 4usize; // "Load: 000%" -> числа x=7, длина 3 let load_x = 7u8; let load_w = 3usize; // "Up:0000s" -> числа x=12, длина 4 let up_x = 12u8; let up_w = 4usize; let mut t: f32 = 21.50; let mut rpm: u32 = 900; let mut load: u32 = 10; let mut uptime: u32 = 0; let spinner = ["|", "/", "-", "\\"]; let mut si = 0usize; loop { // чуть “шевелим” данные t += 0.03; if t > 29.99 { t = 21.50; } rpm = (rpm + 37) % 9999; load = (load + 3) % 100; uptime = uptime.wrapping_add(1); // Важно: обновляем только куски строки в фиксированных местах let temp_s = pad_left(&format!("{:.2}", t), temp_w); let rpm_s = pad_left(&format!("{}", rpm), rpm_w); let load_s = pad_left(&format!("{}", load), load_w); let up_s = pad_left(&format!("{}", uptime % 10000), up_w); let _ = vfd.print_at(temp_x, 1, temp_s); let _ = vfd.print_at(rpm_x, 1, rpm_s); let _ = vfd.print_at(load_x, 2, load_s); let _ = vfd.print_at(up_x, 2, up_s); // “живой” индикатор справа (если ширина позволяет) if width >= 20 { let _ = vfd.print_at(20, 2, spinner[si]); si = (si + 1) % spinner.len(); } std::thread::sleep(Duration::from_millis(delay_ms)); } }