From a549392ccc6e8e86b6522492b656a307bf305767 Mon Sep 17 00:00:00 2001 From: shenjianZ Date: Mon, 18 Nov 2024 15:04:55 +0800 Subject: [PATCH] fix progect --- Cargo.lock | 2 +- Cargo.toml | 7 ++- src/lib.rs | 134 ++++++++++++++++++++++++++++++++++++++++++---------- src/main.rs | 14 ++++-- 4 files changed, 125 insertions(+), 32 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1ec6ded..0a1427e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3,5 +3,5 @@ version = 3 [[package]] -name = "minigrep" +name = "minigrep-cli" version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml index 64c2a3f..ba33180 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,9 @@ [package] -name = "minigrep" +name = "minigrep-cli" version = "0.1.0" edition = "2021" - +description = "use rust implement minimum grep cli program" +license = "MIT" +[profile.dev] +opt-level = 1 [dependencies] diff --git a/src/lib.rs b/src/lib.rs index 7fb3318..f4a375b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,13 +1,68 @@ +//! # Grep CLI Tool +//! +//! 一个简单的命令行工具,用于从文件中搜索指定的查询字符串。 +//! +//! # 功能概述 +//! +//! - 提供命令行接口以执行文本搜索。 +//! - 支持通过环境变量 `IGNORE_CASE` 切换大小写不敏感模式。 +//! - 在遇到错误时提供友好的提示信息。 +//! +//! # 使用方法 +//! +//! 假设程序的可执行文件名为 `grep`,可以通过以下方式运行: +//! +//! ```bash +//! ./grep +//! ``` +//! +//! 例如: +//! ```bash +//! ./grep rust example.txt +//! ``` +//! 如果设置了环境变量 `IGNORE_CASE`,查询会忽略大小写。 +//! - CMD +//! ``` bash +//! IGNORE_CASE=1 ./grep rust example.txt +//! ``` +//! - Powershell +//! ``` powershell +//! $env:IGNORE_CASE = 1 ./grep rust example.txt +//! ``` use std::error::Error; use std::{env, fs}; + +/// 配置结构体,存储查询字符串、文件路径以及是否忽略大小写的标志。 pub struct Config { - query: String, - file_path: String, - ignore_case: bool, + /// 查询字符串 + pub query: String, // 修改为 pub,便于外部访问 + /// 文件路径 + pub file_path: String, // 修改为 pub,便于外部访问 + /// 是否忽略大小写 + pub ignore_case: bool, // 修改为 pub,便于外部访问 } impl Config { - // Create a new Result, - // parse config from args 's iter. + /// 从命令行参数构建 `Config` 实例。 + /// + /// # 参数 + /// + /// - `args`: 命令行参数的迭代器。 + /// + /// # 返回值 + /// + /// 返回 `Config` 实例,或者在参数缺失时返回错误消息。 + /// + /// # 错误 + /// + /// 当缺少查询字符串或文件路径时,返回对应的错误消息。 + /// + /// # 示例 + /// + /// ``` + /// let args = vec!["program".to_string(), "query".to_string(), "file.txt".to_string()]; + /// let config = Config::build(args.into_iter()); + /// assert!(config.is_ok()); + /// ``` pub fn build(mut args: impl Iterator) -> Result { args.next(); let query = match args.next() { @@ -16,7 +71,7 @@ impl Config { }; let file_path = match args.next() { Some(args) => args, - None => return Err("Please provide a file path") + None => return Err("Please provide a file path"), }; let ignore_case = env::var("IGNORE_CASE").is_ok(); Ok(Config { @@ -26,10 +81,21 @@ impl Config { }) } } + +/// 运行搜索逻辑。 +/// +/// # 参数 +/// +/// - `config`: 包含查询信息的 `Config` 实例。 +/// +/// # 返回值 +/// +/// 成功返回 `Ok(())`,失败返回包含错误信息的 `Box`。 +/// +/// # 错误 +/// +/// 如果文件读取失败,返回错误信息。 pub fn run(config: Config) -> Result<(), Box> { - // println!("Query: {}", config.query); - // println!("File path: {}", config.file_path); - // Read the file,if it not exists, return an error(Box) let contents = fs::read_to_string(config.file_path)?; let result = if config.ignore_case { search_case_insensitive(&config.query, &contents) @@ -39,32 +105,47 @@ pub fn run(config: Config) -> Result<(), Box> { for line in result { println!("{line}") } - // print!("File contents: \n{}", contents); Ok(()) } -fn search<'a>(query: &str, contents: &'a str) -> Vec<&'a str> { - // let mut results = Vec::new(); - // for line in contents.lines() { - // if line.contains(query) { - // results.push(line); - // } - // } - // results - contents.lines() - .filter(|line| line.contains(query)) - .collect() -} -fn search_case_insensitive<'a>(query: &str, contents: &'a str) -> Vec<&'a str> { +/// 在内容中进行大小写敏感的查询。 +/// +/// # 参数 +/// +/// - `query`: 查询字符串。 +/// - `contents`: 文件内容。 +/// +/// # 返回值 +/// +/// 包含匹配行的 `Vec<&str>`。 +fn search<'a>(query: &str, contents: &'a str) -> Vec<&'a str> { + contents.lines() + .filter(|line| line.contains(query)) + .collect() +} + +/// 在内容中进行大小写不敏感的查询。 +/// +/// # 参数 +/// +/// - `query`: 查询字符串。 +/// - `contents`: 文件内容。 +/// +/// # 返回值 +/// +/// 包含匹配行的 `Vec<&str>`。 +fn search_case_insensitive<'a>(query: &str, contents: &'a str) -> Vec<&'a str> { let query = query.to_lowercase(); contents.lines() - .filter(|line| line.to_lowercase().contains(&query)) - .collect() + .filter(|line| line.to_lowercase().contains(&query)) + .collect() } + #[cfg(test)] mod tests { use super::*; + /// 测试大小写敏感的查询功能。 #[test] fn case_sensitive() { let query = "duct"; @@ -77,6 +158,7 @@ Duct tape."; assert_eq!(vec!["safe, fast, productive."], search(query, contents)); } + /// 测试大小写不敏感的查询功能。 #[test] fn case_insensitive() { let query = "rUsT"; @@ -91,4 +173,4 @@ Trust me."; search_case_insensitive(query, contents) ); } -} +} \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index ab93d49..c852ab9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,16 +1,24 @@ use std::env as ENV; use std::process; + +/// `main` 函数是程序的入口点。 +/// +/// 此函数解析命令行参数,并调用 `minigrep` 库中的功能来执行搜索。 +/// 如果参数解析或程序运行中出现错误,将打印错误信息并退出。 fn main() { - println!("-------------Grep Cli Tool-------------"); + println!("-------------Grep CLI Tool-------------"); println!("Usage : grep "); println!("------------------End------------------"); - // let config = minigrep::Config::new(ENV::args()); + + // 通过 `minigrep::Config::build` 解析命令行参数。 let config = minigrep::Config::build(ENV::args()).unwrap_or_else(|err| { eprintln!("Problem parsing arguments: {err}"); process::exit(1); }); + + // 调用 `minigrep::run` 执行搜索逻辑,并处理可能的错误。 if let Err(e) = minigrep::run(config) { - println!("Application error: {}", e); + eprintln!("Application error: {}", e); process::exit(1); }; }