|
| 1 | +//! # dzh_crate |
| 2 | +//! |
| 3 | +//! crate.io 的测试,此包实现了“读取命令行输入,查找对应路径文件中文本拥有对应字段的行,并打印输出。” |
| 4 | +/// # ExampleS |
| 5 | +/// |
| 6 | +/// ''' |
| 7 | +///let query = "duct"; |
| 8 | +/// let contents = "\ |
| 9 | +/// Rust: |
| 10 | +/// safe, fast, productive. |
| 11 | +/// Pick three."; |
| 12 | +/// assert_eq!(vec!["safe, fast, productive."], search(query, contents)); |
| 13 | +/// ''' |
| 14 | +
|
| 15 | +use std::error::Error; |
| 16 | +use std::fs; |
| 17 | +use std::env; |
| 18 | +pub struct Config{ |
| 19 | + pub query:String, |
| 20 | + pub file_path:String, |
| 21 | + pub ignore_case: bool, |
| 22 | +} |
| 23 | +// impl Config { |
| 24 | +// pub fn build(args: &[String]) -> Result<Config, &'static str> { |
| 25 | +// if args.len() < 3 { |
| 26 | +// return Err("not enough arguments"); |
| 27 | +// } |
| 28 | + |
| 29 | +// let query = args[1].clone(); |
| 30 | +// let file_path = args[2].clone(); |
| 31 | +// let ignore_case = env::var("IGNORE_CASE").is_ok(); |
| 32 | +// Ok(Config { query, file_path,ignore_case }) |
| 33 | +// } |
| 34 | +// } |
| 35 | +impl Config { |
| 36 | + pub fn build( |
| 37 | + mut args: impl Iterator<Item = String>, //参数是一个可变且实现了string迭代器的东西 |
| 38 | + ) -> Result<Config, &'static str> { //返回值是一个oresult,成功是config,失败了就是错误信息 |
| 39 | + args.next(); |
| 40 | + |
| 41 | + let query = match args.next() { //对迭代器中的下一个值,因为这个值是option进行模式匹配 |
| 42 | + Some(arg) => arg,//如果有值,就返回一个arg |
| 43 | + None => return Err("Didn't get a query string"), |
| 44 | + }; |
| 45 | + |
| 46 | + let file_path = match args.next() { |
| 47 | + Some(arg) => arg, |
| 48 | + None => return Err("Didn't get a file path"), |
| 49 | + }; |
| 50 | + //检查环境变量是否存在ignore_case=1,如果有则设置bool为真,意思就是忽略大小写。 |
| 51 | + let ignore_case = env::var("IGNORE_CASE").is_ok(); |
| 52 | + |
| 53 | + Ok(Config { //如果都没错,就用传入的这些值创建一个config实例并返回 |
| 54 | + query, |
| 55 | + file_path, |
| 56 | + ignore_case, |
| 57 | + }) |
| 58 | + } |
| 59 | +} |
| 60 | + |
| 61 | +pub fn run(config:&Config) ->Result<(),Box<dyn Error>> { |
| 62 | + let contents = fs::read_to_string(&config.file_path)?; //正常会从配置路径中读取相关文件的内容,如果错误 就会在这里return错误信息 |
| 63 | + |
| 64 | + if config.ignore_case { //检查环境变量,并分别查找大小写是否敏感的字段。 |
| 65 | + search_case_insensitive(&config.query, &contents) |
| 66 | + } else { |
| 67 | + search(&config.query, &contents) |
| 68 | + }; |
| 69 | + |
| 70 | + |
| 71 | + Ok(()) //如果一直顺利执行就返回一个空的ok值 |
| 72 | +} |
| 73 | +/// # ExampleS |
| 74 | +/// |
| 75 | +/// ``` |
| 76 | +/// let query = "duct"; |
| 77 | +/// let contents = "\ |
| 78 | +/// Rust: |
| 79 | +/// safe, fast, productive. |
| 80 | +/// Pick three."; |
| 81 | +/// assert_eq!(vec!["safe, fast, productive."], minigrep::search(query, contents)); |
| 82 | +/// ``` |
| 83 | +///为了满足需求,我需要设计一个search函数,把他放到run中,让他获取查询字段和文本,以一个拥有所有权的string向量,返回包含查询字段的行。. |
| 84 | +
|
| 85 | +pub fn search (query:&str,contents:&str)-> Vec<String>{//为了满足需求,我需要设计一个search函数,把他放到run中,让他获取查询字段和文本,以一个拥有所有权的string向量,返回包含查询字段的行。 |
| 86 | + let lines_of_contents:Vec<String>=contents.lines() |
| 87 | + .filter(|line| line.contains(query)) |
| 88 | + .map(|line| line.trim().to_string()).collect(); // 使用 trim() 移除每行开头和结尾的所有空白字符,然后用to_string来创建一个新的String实例,最后collect起来变成vec。 |
| 89 | + println!("{:?}",lines_of_contents); |
| 90 | + lines_of_contents |
| 91 | +} |
| 92 | + |
| 93 | +pub fn search_case_insensitive(query: &str,contents: &str,) -> Vec<String> { |
| 94 | + let lines_of_contents:Vec<String>=contents.lines() |
| 95 | + .filter(|line|line.to_lowercase().contains(&query.to_lowercase())) |
| 96 | + .map(|line| line.trim().to_string()).collect(); |
| 97 | + println!("{:?}",lines_of_contents); |
| 98 | + lines_of_contents |
| 99 | +} |
| 100 | + |
| 101 | +//为测试驱动开发准备模块 |
| 102 | +#[cfg(test)] //配置属性,表示一段代码只在测试时编译 |
| 103 | +mod tests { |
| 104 | + use super::*; |
| 105 | + |
| 106 | + #[test] |
| 107 | + fn case_sensitive() { |
| 108 | + let query = "duct"; |
| 109 | + let contents = "\ |
| 110 | + Rust: |
| 111 | + safe, fast, productive. |
| 112 | + Pick three."; |
| 113 | + |
| 114 | + assert_eq!(vec!["safe, fast, productive."], search(query, contents)); |
| 115 | + } |
| 116 | + |
| 117 | + #[test] |
| 118 | + fn case_unsensitive(){ |
| 119 | + let query = "rUsT"; |
| 120 | + let contents = "\ |
| 121 | + Rust: |
| 122 | + safe, fast, productive. |
| 123 | + Pick three. |
| 124 | + Trust me."; |
| 125 | + |
| 126 | + assert_eq!( |
| 127 | + vec!["Rust:", "Trust me."], |
| 128 | + search_case_insensitive(query, contents) |
| 129 | + ); |
| 130 | + } |
| 131 | +} |
0 commit comments