实现 Config::build 方法以解析命令行参数并更新主函数以使用新方法

This commit is contained in:
rsgl 2024-11-24 23:29:35 +08:00
parent 21970c04d5
commit 5490f28e43
2 changed files with 54 additions and 19 deletions

View File

@ -8,6 +8,27 @@ pub struct Config {
} }
impl Config { impl Config {
pub fn build(mut args: impl Iterator<Item = String>) -> Result<Config, &'static str> {
args.next();
let query = match args.next() {
Some(arg) => arg,
None => return Err("query not provided"),
};
let file_path = match args.next() {
Some(arg) => arg,
None => return Err("file path not provided"),
};
let ignore_case = env::var("IGNORE_CASE").is_ok();
Ok(Config {
query,
file_path,
ignore_case,
})
}
pub fn new(args: &[String]) -> Result<Config, &'static str> { pub fn new(args: &[String]) -> Result<Config, &'static str> {
if args.len() < 3 { if args.len() < 3 {
return Err("not enough arguments"); return Err("not enough arguments");
@ -28,8 +49,10 @@ impl Config {
pub fn run(config: Config) -> Result<(), Box<dyn Error>> { pub fn run(config: Config) -> Result<(), Box<dyn Error>> {
let contents = fs::read_to_string(config.file_path)?; let contents = fs::read_to_string(config.file_path)?;
let results = if config.ignore_case { let results = if config.ignore_case {
println!("Ignoring case");
search_case_insensitive(&config.query, &contents) search_case_insensitive(&config.query, &contents)
} else { } else {
println!("Case sensitive");
search(&config.query, &contents) search(&config.query, &contents)
}; };
@ -80,24 +103,32 @@ Trust me.";
} }
pub fn search<'a>(query: &str, contents: &'a str) -> Vec<&'a str> { pub fn search<'a>(query: &str, contents: &'a str) -> Vec<&'a str> {
let mut result = Vec::new(); // let mut result = Vec::new();
for line in contents.lines() { // for line in contents.lines() {
if line.contains(&query) { // if line.contains(&query) {
result.push(line); // result.push(line);
} // }
} // }
result // result
contents
.lines()
.filter(|line| line.contains(&query))
.collect()
} }
pub fn search_case_insensitive<'a>(query: &str, contents: &'a str) -> Vec<&'a str> { pub fn search_case_insensitive<'a>(query: &str, contents: &'a str) -> Vec<&'a str> {
let query = query.to_lowercase(); // let query = query.to_lowercase();
let mut result = Vec::new(); // let mut result = Vec::new();
for line in contents.lines() { // for line in contents.lines() {
if line.to_lowercase().contains(&query) { // if line.to_lowercase().contains(&query) {
result.push(line); // result.push(line);
} // }
} // }
result // result
contents
.lines()
.filter(|line| line.to_lowercase().contains(&query.to_lowercase()))
.collect()
} }

View File

@ -4,9 +4,13 @@ use std::process;
use minigrep::Config; use minigrep::Config;
fn main() { fn main() {
let args: Vec<String> = env::args().collect(); // let args: Vec<String> = env::args().collect();
let config = Config::new(&args).unwrap_or_else(|err| { // let config = Config::new(&args).unwrap_or_else(|err| {
println!("Problem parsing arguments: {}", err); // eprintln!("Problem parsing arguments: {}", err);
// process::exit(1);
// });
let config = Config::build(env::args()).unwrap_or_else(|err| {
eprintln!("Problem parsing arguments: {}", err);
process::exit(1); process::exit(1);
}); });
@ -14,7 +18,7 @@ fn main() {
println!("In file {}", config.file_path); println!("In file {}", config.file_path);
if let Err(e) = minigrep::run(config) { if let Err(e) = minigrep::run(config) {
println!("Application error: {}", e); eprintln!("Application error: {}", e);
process::exit(1); process::exit(1);
} }
} }