Rust状态栏插件库status-line的使用,轻量级状态栏显示与实时信息更新工具

Rust状态栏插件库status-line的使用,轻量级状态栏显示与实时信息更新工具

status-line是一个Rust库,允许你在终端中显示状态和进度信息。它解决了在终端中显示少量文本信息、定期刷新并最终擦除的问题,类似于进度条的显示方式。

特性

  1. 将状态线视为进度条的通用化形式
  2. 不强制要求将状态文本渲染为进度条
  3. 不强制任何特定的数据格式或模板
  4. 使用标准的Display trait将数据转换为打印文本
  5. 状态更新频率可高达每秒数千万次
  6. 使用后台线程以低频处理文本打印,解耦重绘率和数据更新率

示例

use std::fmt::{Display, Formatter};
use std::sync::atomic::{AtomicU64, Ordering};
use status_line::StatusLine;

// 定义代表应用程序状态的数据模型
// 确保它是Send + Sync,以便从不同线程读写:
struct Progress(AtomicU64);

// 定义如何显示它:
impl Display for Progress {
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        write!(f, "{}%", self.0.load(Ordering::Relaxed))
    }
}

// StatusLine负责显示进度数据:
let status = StatusLine::new(Progress(AtomicU64::new(0)));   // 显示0%
status.0.fetch_add(1, Ordering::Relaxed);                    // 显示1%
status.0.fetch_add(1, Ordering::Relaxed);                    // 显示2%
drop(status)                                                 // 隐藏状态线

完整示例

以下是一个更完整的示例,展示如何使用status-line显示多线程任务进度:

use std::fmt::{Display, Formatter};
use std::sync::atomic::{AtomicU64, Ordering};
use std::sync::Arc;
use std::thread;
use std::time::Duration;
use status_line::StatusLine;

// 定义状态数据结构
#[derive(Debug)]
struct TaskStatus {
    completed: AtomicU64,
    total: u64,
    thread_count: u32,
}

impl Display for TaskStatus {
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        let completed = self.completed.load(Ordering::Relaxed);
        let percentage = (completed as f64 / self.total as f64) * 100.0;
        write!(
            f, 
            "进度: {}/{} ({:.2}%) | 线程数: {}",
            completed, 
            self.total, 
            percentage,
            self.thread_count
        )
    }
}

fn main() {
    // 初始化状态
    let status = Arc::new(StatusLine::new(TaskStatus {
        completed: AtomicU64::new(0),
        total: 100,
        thread_count: 4,
    }));

    // 创建多个线程模拟并行任务
    let mut handles = vec![];
    for _ in 0..status.data().thread_count {
        let status = status.clone();
        handles.push(thread::spawn(move || {
            for _ in 0..25 {
                thread::sleep(Duration::from_millis(100));
                status.data().completed.fetch_add(1, Ordering::Relaxed);
            }
        }));
    }

    // 等待所有线程完成
    for handle in handles {
        handle.join().unwrap();
    }

    // status在离开作用域时会自动清理显示
}

安装

将以下内容添加到你的Cargo.toml中:

status-line = "0.2.0"

或者运行以下命令:

cargo add status-line

许可证

MIT许可证


1 回复

Rust状态栏插件库status-line使用指南

介绍

status-line是一个轻量级的Rust库,用于在终端应用程序中创建和管理状态栏。它允许开发者轻松显示实时信息,如进度、系统状态或其他动态数据,而无需复杂的UI框架。

主要特性:

  • 轻量级且高效
  • 支持实时更新状态信息
  • 可自定义显示格式
  • 线程安全
  • 支持多行状态显示

安装

在Cargo.toml中添加依赖:

[dependencies]
status-line = "0.3"

基本使用方法

简单示例

use status_line::StatusLine;

fn main() {
    // 创建一个状态栏
    let status = StatusLine::new();
    
    // 设置状态信息
    status.update("Processing...");
    
    // 模拟工作
    for i in 0..=100 {
        status.update(&format!("Progress: {}%", i));
        std::thread::sleep(std::time::Duration::from_millis(50));
    }
    
    // 完成时清除状态栏
    status.clear();
    println!("Done!");
}

多部分状态显示

use status_line::{StatusLine, StatusPart};

fn main() {
    let status = StatusLine::new();
    
    // 创建多个状态部分
    let part1 = StatusPart::new("Downloading");
    let part2 = StatusPart::new("0%");
    let part3 = StatusPart::new("[====>      ]");
    
    // 组合显示
    status.update_parts(&[&part1, &part2, &part3]);
    
    // 更新部分状态
    for i in 0..=100 {
        part2.update(&format!("{}%", i));
        let progress = format!("[{}{}]", "=".repeat(i/10), " ".repeat(10 - i/10));
        part3.update(&progress);
        std::thread::sleep(std::time::Duration::from_millis(100));
    }
    
    status.clear();
}

高级用法

多行状态

use status_line::{StatusLine, StatusPart};

fn main() {
    let status = StatusLine::new().multiline(true);
    
    let line1_part1 = StatusPart::new("Task 1:");
    let line1_part2 = StatusPart::new("In progress");
    
    let line2_part1 = StatusPart::new("Task 2:");
    let line2_part2 = StatusPart::new("Waiting");
    
    status.update_parts(&[&line1_part1, &line1_part2]);
    status.add_line();
    status.update_parts(&[&line2_part1, &line2_part2]);
    
    // 更新不同行的状态
    line1_part2.update("Completed");
    line2_part2.update("In progress");
    
    std::thread::sleep(std::time::Duration::from_secs(2));
    status.clear();
}

自定义样式

use status_line::{StatusLine, StatusPart};
use colored::Colorize;

fn main() {
    let status = StatusLine::new();
    let part1 = StatusPart::new("Status:").bold();
    let part2 = StatusPart::new("OK").green();
    
    status.update_parts(&[&part1, &part2]);
    
    // 错误状态时改变颜色
    part2.update("ERROR").red();
    
    std::thread::sleep(std::time::Duration::from_secs(2));
    status.clear();
}

线程安全使用

use status_line::StatusLine;
use std::sync::Arc;
use std::thread;

fn main() {
    let status = Arc::new(StatusLine::new());
    
    let status_clone = status.clone();
    thread::spawn(move || {
        for i in 0..=50 {
            status_clone.update(&format!("Thread 1: {}", i));
            thread::sleep(std::time::Duration::from_millis(100));
        }
    });
    
    for i in 0..=50 {
        status.update(&format!("Main thread: {}", i));
        thread::sleep(std::time::Duration::from_millis(150));
    }
    
    status.clear();
}

完整示例

以下是一个结合了多种功能的完整示例:

use status_line::{StatusLine, StatusPart};
use colored::Colorize;
use std::sync::Arc;
use std::thread;
use std::time::Duration;

fn main() {
    // 创建多行状态栏
    let status = Arc::new(StatusLine::new().multiline(true));
    
    // 第一行:下载进度
    let download_label = StatusPart::new("Download:").bold();
    let download_progress = StatusPart::new("0%").blue();
    let download_bar = StatusPart::new("[          ]");
    
    // 第二行:系统状态
    let system_label = StatusPart::new("System:").bold();
    let system_status = StatusPart::new("OK").green();
    let cpu_usage = StatusPart::new("CPU: 0%");
    
    // 组合显示
    status.update_parts(&[&download_label, &download_progress, &download_bar]);
    status.add_line();
    status.update_parts(&[&system_label, &system_status, &cpu_usage]);
    
    // 模拟下载线程
    let status_clone = status.clone();
    thread::spawn(move || {
        for i in 0..=100 {
            download_progress.update(&format!("{}%", i));
            let bar = format!("[{}{}]", "=".repeat(i/10), " ".repeat(10 - i/10));
            download_bar.update(&bar);
            
            // 每10%更新一次CPU状态
            if i % 10 == 0 {
                let cpu = i % 70 + 10;
                cpu_usage.update(&format!("CPU: {}%", cpu));
                
                // 当CPU过高时显示警告
                if cpu > 60 {
                    system_status.update("WARNING").yellow();
                } else {
                    system_status.update("OK").green();
                }
            }
            
            thread::sleep(Duration::from_millis(100));
        }
    });
    
    // 主线程等待下载完成
    thread::sleep(Duration::from_secs(11));
    
    // 完成时显示最终状态
    system_status.update("IDLE").cyan();
    cpu_usage.update("CPU: 5%");
    
    thread::sleep(Duration::from_secs(2));
    status.clear();
    println!("所有任务已完成!");
}

注意事项

  1. 在长时间运行的程序结束时调用clear(),以免状态信息残留
  2. 频繁更新状态(>30次/秒)可能会导致显示闪烁
  3. 在多线程环境中使用Arc包装StatusLine
  4. 某些终端可能需要特殊处理才能正确显示状态栏

status-line库为Rust终端应用提供了简单而强大的状态显示功能,适合需要实时反馈的CLI工具和应用程序。

回到顶部