首先cargo new minigrep 创建一个名为minigrep的项目文件
cd minigrep 进入文件
code . 用vscode打开该文件
我们为了使项目看着整洁,在main.rs中写调用实现,在lib.rs中写方法实现
由于项目需要,创建一个poem.txt的文件
main.rs中的代码
use std::env;
use std::process;
use minigrep::{Config, run};
fn main(){
let args:Vec<String> = env::args().collect();
let config = Config::new(&args).unwrap_or_else(|err|{
eprintln!("Problem parsing argument: {}", err);//标准错误输出
process::exit(0);
});//Result下的方法unwrap_or_else()若Ok则把Ok中值赋到前面变量
if let Err(e) = run(config){
eprintln!("Application error:{}", e);//标准错误输出
process::exit(0);
}
}
// cargo run I poem.txt > output.txt 命令可以将编译成功的结果输出到output.txt中
// 而错误的结果通过eprintln!输出到终端
lib.rs中的代码
use std::fs;
use std::error::Error;
use std::env;
pub fn run(config:Config)->Result<(), Box<dyn Error>>{//()代表返回为空
let contents =
fs::read_to_string(config.filename)?;//? 发生错误将错误值返回给函数的调用者处理
let result = {if config.case_sensitive{
search(&config.query, &contents)
}else{
search_case_insensitive(&config.query, &contents)
}
};
for line in result{
println!("{}", line);
}
Ok(())
}
impl Config{
pub fn new(args:&Vec<String>)->Result<Config, &str>{
if args.len()<3{
return Err("not enough arguments");
}
let q = args[1].clone();
let f = args[2].clone();
let r = env::var("CASE_INSENSITIVE").is_err();//CASE_INSENSITIVE=1 cargo run I poem.txt命令会输出不区分大小写的行
Ok(Config{
query:q,
filename:f,
case_sensitive:r,
})
}
}
pub struct Config{
pub query:String,
pub filename:String,
pub case_sensitive:bool,
}
pub fn search<'a>(query:&str, contents:&'a str)->Vec<&'a str>{
let mut result:Vec<&str> = vec![];
for line in contents.lines(){//lines函数返回文本的每一行
if line.contains(&query){//contains函数判断是否行中包含某一字符串切片返回bool类型
result.push(line);
}
}
result
}
pub fn search_case_insensitive<'a>(query:&str, contents:&'a str)->Vec<&'a str>{
let mut result:Vec<&str> = vec![];
let query = query.to_lowercase();//to_lowercase函数将字符串切片变为小写
for line in contents.lines(){//lines函数返回文本的每一行
if line.to_lowercase().contains(&query){//contains函数判断是否行中包含某一字符串切片返回bool类型
result.push(line);
}
}
result
}
#[cfg(test)]
mod tests{
use super::*;
#[test]
fn case_sensitive(){
let query = "duct";
let contents = "\
Rust:
safe, fast, productive.
Pick three.
Duct tape.";
assert_eq!(vec!["safe, fast, productive."],
search(query, contents));
}
#[test]
fn case_insensitive(){
let query = "rUsT";
let contents = "\
Rust:
safe, fast, productive.
Pick three.
Trust tape.";
assert_eq!(vec!["Rust:", "Trust tape."],
search_case_insensitive(query, contents));
}
}
最后使用cargo run I poem.txt > output.txt 命令可以将编译成功的结果输出到output.txt中,而错误的结果通过eprintln!输出到终端