rust 终端显示综合例程

文章目录

  • demo程序
  • 1 terminal_size
  • 2 term_grid
  • 3 crossterm
    • 3.1 style
  • 4 lscolors
    • 准备内容
    • 4.1 LsColors
  • 5 users
    • 5.1 获取用户/用户组信息
    • 5.2 通过缓存获取

demo程序

综合demo
各个库使用demo

1 terminal_size

一个获取终端界面大小的库,支持linux、macos、windows。该库比较简洁,只有2个结构体和2个方法

// Height
pub struct Height(pub u16);// Width
pub struct Width(pub u16);// terminal_size
pub fn terminal_size() -> Option<(Width, Height)>// terminal_size_using_fd
// 如果可用,则使用给定的文件描述符返回终端的大小。
// 如果给定的文件描述符不是 tty,则返回None
pub fn terminal_size_using_fd(fd: RawFd) -> Option<(Width, Height)>

使用示例

use terminal_size::{Width, Height, terminal_size};pub fn terminal_size_test(){let size = terminal_size();if let Some((Width(w), Height(h))) = size {println!("Your terminal is {} cols wide and {} lines tall", w, h);} else {println!("Unable to get terminal size");}
}

参考链接

2 term_grid

该库以适合固定宽度字体的网格格式排列文本数据,并使用算法最小化所需空间

参考链接:https://docs.rs/term_grid/latest/term_grid/

示例:

use term_grid::{Grid, GridOptions, Direction, Filling, Cell};pub fn term_grid_test(){let mut grid = Grid::new(GridOptions {filling:    Filling::Spaces(1),             // 列与列之间的分隔direction:  Direction::LeftToRight,         // 方向});for s in &["one", "two", "three", "four", "five", "six", "seven","eight", "nine", "ten", "eleven", "twelve"]{grid.add(Cell::from(*s));   // 添加显示内容}println!("{}", grid.fit_into_width(24).unwrap());   // 显示,设置屏幕宽度 还有一种方式是设置显示列数
}
  1. Cell

    1)字段:

    contents:String //需要显示的内容
    width:Width		//字符串长度
    
  2. GridOption

    传递给Grid::new()网格试图的用户可分配选项

    1)字段

    direction:Direction	// 单元格写入方向
    filling:Filling		// 单元格之间的空格数
    

    direction:LeftToRight(从左到右)

    ​ TopToBottpm(从上到下)

    Filling:Spaces(Width) 空格宽度

    ​ Text(String) 字符串

  3. gird

    使用网格选项来格式化单元格所需的一切

    1)方法:

    // 创建新的网格视图
    fn new(options: GridOptions) -> Self// 在向量中保留空间以容纳要添加的给定数量的额外单元
    fn reserve(&mut self, additional: usize)// 讲一个单元格添加至向量
    fn add(&mut self, cell: Cell)// 返回可现实的网格,该网格已被打包以适合给定的宽度和最少的行数。
    // None如果任何单元格的宽度大于最大宽度,则返回。
    fn fit_into_width(&self, maximum_width: Width) -> Option<Display>// 返回具有给定列数且没有最大宽度的可显示网格。
    fn fit_into_columns(&self, num_columns: usize) -> Display
    
  4. 使用示例

    use term_grid::{Grid, GridOptions, Direction, Filling, Cell};pub fn term_grid_test(){let mut grid = Grid::new(GridOptions {filling:    Filling::Spaces(2),             // 列与列之间的分隔direction:  Direction::LeftToRight,         // 方向});for s in &["one", "two", "three", "four", "five", "six", "seven","eight", "nine", "ten", "eleven", "twelve", "111", "222","333", "444","555", "666", "777", "888", "999","aaa"]{grid.add(Cell::from(*s));   // 添加显示内容}// 显示,设置屏幕宽度 还有一种方式是设置显示列数let print_str = grid.fit_into_columns(1);		// 设置显示列数// let print_str = grid.fit_into_width(14).unwrap();	// 设置显示宽度println!("{}", print_str);
    }// 通过ansi形式显示,可以带颜色显示
    pub fn term_grid_ansi(){let mut grid = Grid::new(GridOptions {filling:    Filling::Spaces(1),             // 列与列之间的分隔direction:  Direction::LeftToRight,         // 方向});let cell: Cell = Cell{width:20,        // 预先计算的字符串宽度contents:String::from("\u{1b}[38;5;105m\u{f001} tests\u{1b}[39m"),};let cell2: Cell = Cell{width:20,        // 预先计算的字符串宽度contents:String::from("\u{1b}[38;5;105m\u{f001} hello\u{1b}[39m"),};grid.add(cell);   // 添加显示内容grid.add(cell2);// println!("{}", grid.fit_into_width(14).unwrap());   // 显示,设置屏幕宽度 还有一种方式是设置显示列数let print_str = grid.fit_into_columns(1).to_string();println!("{}", print_str);
    }
    

3 crossterm

跨平台终端操作库,纯rust库,可以编写跨平台的基于文本的界面。

参考链接:https://docs.rs/crossterm/latest/crossterm/style/index.html

主要作用:

  1. 可以设置终端显示颜色

1)模块

  • 光标模块(cursor):一个处理终端游标的模块
    • 可见性
    • 外貌
    • 位置
  • 事件模块(envent):读取事件的模块。
    • 键盘事件
    • 鼠标事件
  • 风格模块(style):一个在文本上应用属性和颜色的模块。(主要使用的模块)
    • 颜色
    • 属性
  • 终端模块(terminal):一个与终端一起工作的模块。
    • 滚动
    • 各种各样
    • 备用个屏幕

2)命令执行方式

  • 惰性执行:将字节刷新到终端缓冲区是一项反锁的系统调用。如果我们使用终端执行大量操作,我们希望定期执行此操作(例如使用 TUI 编辑器),以便我们可以同时将更多数据刷新到终端缓冲区
  • 直接执行:直接刷新缓冲区

3.1 style

用到的三个模块

contentStyle:可以放在内容上的样式。

Colors :颜色 可以解析ANSI格式

attribues:属性

use crossterm::style::{style, Attribute, Attributes, Color, ContentStyle, StyledContent, Stylize};
use crossterm::style::Color::AnsiValue;// 设置显示内容的背景色
pub fn display_color() {let styled = "Hello there".with(Color::Yellow)        // 文本颜色.on(Color::Blue)            // 背景颜色.attribute(Attribute::Dim);     // 降低文本强度 加强文本就是给显示内容加粗println!("{}", styled);
}// 使用apply方法
pub fn termial_apply() {let style = ContentStyle{foreground_color: Some(Color::Yellow),background_color:Some(Color::Blue),..ContentStyle::default()};let hello = style.apply("hello world");println!("{}", hello);
}// 字符串转换成ansi格式
pub fn str_to_ansi() {let mut strings: Vec<String> = Vec::new();let mut block = Vec::new();let style = ContentStyle {foreground_color: Some(AnsiValue(105)),background_color: None,underline_color: None,// attributes: Attributes(0),attributes:Attributes::default(),};let hello = style.apply(String::from("\u{f0668} tests"));println!("{:#?}", hello.to_string());   // 转换为ansi格式block.push(hello);strings.push(block.into_iter().map(|s| s.to_string()).collect::<Vec<String>>().join(""),);println!("string {:?}", strings);
}

4 lscolors

根据LS_COLORS环境变量为路径着色的库。

参考链接

准备内容

  1. ANSI

    ANSI转义码是一组控制码,用于再文本中添加格式化和颜色,这些码已ESC字符为开头,通常是\x1b\033\e开始(都是exc), 后面紧跟一系列参数和指令。在ANSI标准中,这些码通常用于控制终端的文本输出。是否支持ANSI格式显示 和显示终端有关(putty就可以支持ANSI格式显示)。

  2. 示例:

    echo -e "\e[37;44;3;1mLYL\e[0m"
    

    \e:开始ANSI

    [:转移序列开始字符

    37;44;3;1:已;分割,37(前景色) 44(背景色) 3(斜体) 1(加粗)

    m:结束控制符序列

    LYL:显示的内容

    \e[0m:重置文本样式

    执行结果:
    在这里插入图片描述

  3. 颜色列表

    https://blog.csdn.net/linux_rm/article/details/129477692

  4. ANSI转义码:https://en.wikipedia.org/wiki/ANSI_escape_code

4.1 LsColors

根据环境变量为路径着色

保存着如何为不同文件系统着色/设置样式的信息

  1. 初始化LsColors方法

    fn empty()->Self	// 创建一个空的LsColors
    fn from_env()->Option<Self>		// 从LS_COLORS环境变量创建一个新的LsColors实例
    fn from_string(input:&str)->Self	// 从字符串创建一个LsColors
    
  2. 获取style(ANSI字体风格)方法

    fn style_for_path <PAsRef <Path>> ( &self,path:P) -> Option <& Style >			// 获取给定路径的ANSI样式
    fn style_for<F: Colorable>(&self, file: &F) -> Option<&Style>	// 获取可着色路径的ANSI样式
    fn style_for_str(&self, file_str: &str) -> Option<&Style>		//获取字符串的 ANSI 样式。
    fn style_for_path_with_metadata<P: AsRef<Path>>(&self,path: P,metadata: Option<&Metadata>
    ) -> Option<&Style>				// 给定相应的结构,获取路径的 ANSI 样式Metadata。
    fn style_for_path_components<'a>(&'a self,path: &'a Path
    ) -> StyledComponents<'a> 		// 获取给定路径的每个组件的 ANSI 样式。组件已包含路径分隔符(如果需要)。对于类似这样的路径foo/bar/test.md,这将返回三个路径组件的三对迭代器foo/,bar/以及test.md 它们各自的样式。
    fn style_for_indicator(&self, indicator: Indicator) -> Option<&Style>		// 获取某个Indicator(常规文件、目录、符号链接等)的 ANSI 样式
    
  3. 简单使用示例

    1. 通过indicator设置颜色

      use lscolors::{LsColors, Indicator, Style}; // 假设的库和模块路径  pub fn lscolor_indicator() {  // 初始化 Lscolors 实例,通常从环境变量或配置文件中加载  let lscolors = LsColors::from_env().unwrap_or_default();  // 假设我们有一些指示器(通常是文件名的一部分或属性)  let indicators = ["di", "ln", "so", "pi", "ex", "bd", "cd", "su", "sg", "tw", "ow", "st", "ow", "*"];  // 遍历指示器并打印相应的颜色样式  for indicator in indicators { let indr= lscolors::Indicator::from(indicator).unwrap();  let style = lscolors.style_for_indicator(indr);     // 设置前景色、背景色、下划线、字体样式  不同风格的系统颜色不同,字体样式也不相同// println!("Indicator: {}, Style: {:#?}", indicator, style);  // 如果我们有一个字符串想要应用这个样式,可以这样做(这里仅示例,实际可能需要一个库来处理 ANSI 样式)  let sample_text = "Sample Text";  // let styled_text = format!("\x1b[{:#?}m{}\x1b[0m", style, sample_text);  // print!("{}", styled_text); // 注意:在某些环境中可能需要特殊处理才能看到颜色  let ansi_style = style.map(Style::to_nu_ansi_term_style).unwrap_or_default();   // 转换成nu_ansi_term库中的风格println!("{}  {}", indicator,ansi_style.paint(sample_text));    // 绘制给定文本 返回ansi字符串     }  
      }
      
    2. 通过文件类型显示不同颜色

      pub fn lscolor_path() {let lscolors = LsColors::from_env().unwrap_or_default();// let path = "some/folder/archive.zip";// let path = "some/folder/archive.txt";let path = "some/folder/archive.rs";let style = lscolors.style_for_path(path);// If you want to use `nu_ansi_term`:let ansi_style = style.map(Style::to_nu_ansi_term_style).unwrap_or_default();println!("{}", ansi_style.paint(path));}
      

5 users

这是一个用于获取Unix用户和组信息的库。它支持获取系统用户

在Unix中,每个用户都有一个单独的用户ID,每个进程都有一个有效的用户ID,表明它正在使用哪个用户的权限。此外,用户可以是组的成员,组也有名称和id。

此功能在C标准库libc中公开,但作为不安全的Rust接口。这个包装器库提供了一个安全的接口,使用User和Group类型和函数,如get_user_by_uid,而不是低级指针和字符串。它还提供基本的缓存功能。它(还)提供编辑功能;返回值为只读。

参考链接

5.1 获取用户/用户组信息

要是用0.11.3版本,0.11.0 版本的group有问题

pub fn get_user_name() {// 方式1// let user = get_user_by_uid(get_current_uid()).unwrap();// println!("当前用户为 {}", user.name().to_string_lossy());// 方式2// 使用get_current_user_namelet user_name = get_current_username().unwrap();println!("当前用户为:{}", user_name.into_string().unwrap())
}pub fn get_group_name() {// let group = get_group_by_gid(get_current_gid()).unwrap();// println!("当前用户组为 {}", group.name().to_string_lossy());// 使用get_current_user_namelet group_name = get_current_username().unwrap();println!("当前用户组为:{}", group_name.into_string().unwrap())
}

5.2 通过缓存获取

由于users表更改的频率非常低,因此对于短时间运行的程序来说,通常会缓存结果,而不是每次都获取最新的条目。UsersCache类型对此有所帮助,它提供了与此crate中的其他方法具有相同名称的方法,只有它们存储结果。

// 通过缓存方式获取
pub struct Cache {user:UsersCache,group:UsersCache,
}impl Cache {fn new() -> Self{let user = UsersCache::new();let group = UsersCache::new();Self{user,group,}}
}pub fn get_ug_name() {let name= Cache::new();let user = name.user.get_user_by_uid(get_current_uid()).unwrap();let group = name.group.get_group_by_gid(get_current_gid()).unwrap();let user_name = user.name().to_string_lossy();let group_name = group.name().to_string_lossy();println!("user name:{}", user_name);println!("group name:{}", group_name);
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/865669.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

keil5模拟 仿真 报错没有读写权限

debug*** error 65: access violation at 0x4002100C : no write permission 修改为&#xff1a; Dialog DLL默认是DCM3.DLL Parameter默认是-pCM3 应改为 Dialog DLL默认是DARMSTM.DLL Parameter默认是-pSTM32F103VE

【机器学习】机器学习与电商推荐系统的融合应用与性能优化新探索

文章目录 引言第一章&#xff1a;机器学习在电商推荐系统中的应用1.1 数据预处理1.1.1 数据清洗1.1.2 数据归一化1.1.3 特征工程 1.2 模型选择1.2.1 协同过滤1.2.2 矩阵分解1.2.3 基于内容的推荐1.2.4 混合推荐 1.3 模型训练1.3.1 梯度下降1.3.2 随机梯度下降1.3.3 Adam优化器 …

苹果电脑如何录屏,3个方法,帮你搞定

“最近新买了一台苹果电脑&#xff0c;但这是我第一次使用&#xff0c;有很多功能都不太了解。想问问大家苹果电脑如何录屏啊&#xff1f;可以教我一下吗&#xff1f;先提前谢谢大家啦&#xff01;” 苹果电脑以其出色的性能和独特的设计&#xff0c;深受全球用户的喜爱。而在…

Win11禁止右键菜单折叠的方法

背景 在使用windows11的时候&#xff0c;会发现默认情况下&#xff0c;右键菜单折叠了。以至于在使用一些软件的右键菜单时总是要点击“显示更多选项”菜单展开所有菜单&#xff0c;然后再点击。而且每次在显示菜单时先是全部展示&#xff0c;再隐藏一下&#xff0c;看着着实难…

源代码层面分析Appium-inspector工作原理

Appium-inspector功能 Appium Inspector 基于 Appium 框架&#xff0c;Appium 是一个开源工具&#xff0c;用于自动化移动应用&#xff08;iOS 和 Android&#xff09;和桌面应用&#xff08;Windows 和 Mac&#xff09;。Appium 采用了客户端-服务器架构&#xff0c;允许用户通…

51单片机嵌入式开发:STC89C52操作8八段式数码管原理

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 STC89C52操作8八段式数码管原理 1 8位数码管介绍1.1 8位数码管概述1.2 8位数码管原理1.3 应用场景 2 原理图图解2.1 74HC573原理2.2 74HC138原理2.3 数码管原理 3 数码管程序…

豪车视频改字,节假日祝福视频改字小程序制作搭建开发

目录 前言&#xff1a; 一、视频改字小程序功能介绍 二、怎么对短视频模板进行改字&#xff1f; 三、这个短视频改字的项目怎么样&#xff1f; 总结&#xff1a; 前言&#xff1a; 现在很多豪车改字的短视频&#xff0c;节假日祝福的小视频&#xff0c;有不少直播在弄这个…

使用 HBuilder X 进行 uniapp 小程序开发遇到的问题合集

文章目录 背景介绍问题集锦1. 在 HBuilderX 点击浏览器运行时&#xff0c;报 uni-app vue3编译器下载失败 安装错误2.在 HBuilderX 点击微信小程序运行时&#xff0c;报 微信开发者工具打开项目失败&#xff0c;请参阅启动日志错误 背景介绍 HBuilder X 版本&#xff1a;HBui…

一文包学会ElasticSearch的大部分应用场合

ElasticSearch 官网下载地址&#xff1a;Download Elasticsearch | Elastic 历史版本下载地址1&#xff1a;Index of elasticsearch-local/7.6.1 历史版本下载地址2&#xff1a;Past Releases of Elastic Stack Software | Elastic ElasticSearch的安装(windows) 安装前所…

Rust学习笔记007:Trait --- Rust的“接口”

Trait 在Rust中&#xff0c;Trait&#xff08;特质&#xff09;是一种定义方法集合的机制&#xff0c;类似于其他编程语言中的接口&#xff08;java&#xff09;或抽象类(c的虚函数)。 。Trait 告诉 Rust 编译器: 某种类型具有哪些并且可以与其它类型共享的功能Trait:抽象的…

【C++】#1

关键字&#xff1a; 基本框架、多个main执行、快捷键、cout规则 基本框架&#xff1a; #include <iostream> using namespace std;int main() {//具体内容return 0; } 多个main函数可执行&#xff1a; 常用快捷键&#xff1a; cout规则&#xff1a;

Qt中文乱码如何解决

目录 一、使用建议 二、其它设置 一、使用建议 Qt对中文的支持不是很友好&#xff0c;使用QtCreator会出现各种乱七八糟的中文代码问题&#xff0c;如何处理这种问题&#xff1f; &#xff08;1&#xff09;粘贴别人的代码时&#xff0c;先在记事本里粘贴一遍&#xff0c;再…

信号与系统-实验5 离散时间系统的时域分析

一、实验目的 1、理解离散信号的定义与时域特征&#xff0c;掌握在时域求解信号的各种变换运算&#xff1b; 2、掌握离散系统的单位响应及其 MATLAB 实现的方法&#xff1b; 3、掌握离散时间序列卷积及其 MATLAB 实现的方法&#xff1b; 4、掌握利用 MATLAB 求解微分方程&a…

Android隐藏状态栏和修改状态栏颜色_亲测有效

本文记录了隐藏状态栏和修改状态栏颜色以及电量、WiFi标志等内容的模式显示&#xff0c;亲测有效。 1、隐藏屏幕状态栏 public void hideStatusBar(BaseActivity activity) {Window window activity.getWindow();//没有这一行无效window.addFlags(WindowManager.LayoutParam…

新手教学系列——慎用Flask-SQLAlchemy慢日志记录

在使用 Flask-SQLAlchemy 开发应用时&#xff0c;了解和避免潜在的问题是非常重要的。特别是在常驻进程和循环执行任务的场景下&#xff0c;慢查询记录功能&#xff08;SQLALCHEMYRECORDQUERIES&#xff09;可能会引发严重的内存泄漏问题。本文将详细介绍这个问题&#xff0c;并…

博通 VMware 不再支持中文?到底还有哪款虚拟机值得一用?

号主&#xff1a;老杨丨11年资深网络工程师&#xff0c;更多网工提升干货&#xff0c;请关注公众号&#xff1a;网络工程师俱乐部 下午好啊&#xff0c;我的网工朋友。 说起虚拟机&#xff0c;VMware绝对是永远的一哥。 但VMware最近真的“消息”不断啊…… 就上个月&#x…

【Python机器学习】算法链与管道——用预处理进行参数选择的注意项

对于许多机器学习算法&#xff0c;提供的特定数据表示非常重要。比如&#xff0c;首先对数据进行缩放&#xff0c;然后手动合并特征&#xff0c;再利用无监督机器学习来学习特征。因此&#xff0c;大多数机器学习应用不仅需要应用多个算法&#xff0c;而且还需要将许多不同的处…

ByteTrack论文阅读笔记

目录 ByteTrack: Multi-Object Tracking by Associating Every Detection Box摘要INTRODUCTION — 简介BYTE算法BYTE算法用Python代码实现实验评测指标轻量模型的跟踪性能 总结SORT算法简介ByteTrack算法和SORT算法的区别 ByteTrack: Multi-Object Tracking by Associating Eve…

QT加载安装外围依赖库的翻译文件后翻译失败的现象分析:依赖库以饿汉式的形式暴露单例接口导致该现象的产生

1、前提说明 VS2019 QtClassLibaryDll是动态库,QtWidgetsApplication4是应用程序。 首先明确:动态库以饿汉式的形式进行单例接口暴露; 然后,应用程序加载动态库的翻译文件并进行全局安装; // ...QTranslator* trans = new QTranslator();//qDebug() << trans->…

暑期大数据人工智能学习-企业项目试岗实训开营

暑期企业项目-试岗实训活动全面开启啦 跟张良均老师学大数据人工智能 不仅可以提供实习证明&#xff0c;有需要话也可以提供实习鉴定报告 √54个热门案例拆解 √40项目实战课程 √27个项目可选 √4个项目方向