110 lines
2.4 KiB
Rust
110 lines
2.4 KiB
Rust
use std::error::Error;
|
|
use std::fs;
|
|
|
|
pub struct Configs {
|
|
pattern: String,
|
|
filename: String,
|
|
is_case_sensitive: bool,
|
|
}
|
|
|
|
impl Configs {
|
|
pub fn new(args: &mut std::env::Args) -> Result<Configs, &'static str> {
|
|
if args.len() < 3 {
|
|
return Err("\
|
|
minigrep [pattern] [filename] case
|
|
adding \"case\" is optional to enable case sensitive grep");
|
|
}
|
|
|
|
args.next();
|
|
|
|
let pattern = match args.next() {
|
|
Some(arg) => arg,
|
|
None => return Err("Pattern Not got")
|
|
};
|
|
|
|
let filename = match args.next() {
|
|
Some(arg) => arg,
|
|
None => return Err("Filenane Not got")
|
|
};
|
|
|
|
let is_case_sensitive = match args.next() {
|
|
Some(arg) => arg == "case",
|
|
None => false
|
|
};
|
|
|
|
Ok(Configs {
|
|
pattern,
|
|
filename,
|
|
is_case_sensitive,
|
|
})
|
|
}
|
|
}
|
|
|
|
pub fn run(conf: Configs) -> Result<(), Box<dyn Error>> {
|
|
let contents: String = fs::read_to_string(conf.filename)?;
|
|
|
|
if conf.is_case_sensitive {
|
|
print_output(search_case_sensitive(&conf.pattern, &contents));
|
|
} else {
|
|
print_output(search_case_insensitive(&conf.pattern, &contents));
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
|
|
pub fn search_case_sensitive<'a>(pattern: &str, contents: &'a str) -> Vec<&'a str> {
|
|
contents.lines()
|
|
.filter(
|
|
|lin| lin
|
|
.contains(&pattern))
|
|
.collect()
|
|
}
|
|
|
|
pub fn search_case_insensitive<'a>(pattern: &str, contents: &'a str) -> Vec<&'a str> {
|
|
contents.lines()
|
|
.filter(
|
|
|lin| lin.to_lowercase()
|
|
.contains(&pattern.to_lowercase()))
|
|
.collect()
|
|
}
|
|
|
|
pub fn print_output(out: Vec<&str>) {
|
|
println!("matched: {}", out.len());
|
|
for x in out {
|
|
println!("{}", x);
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn case_sensitive() {
|
|
let pattern = "duct";
|
|
let contents = "\
|
|
Rust:
|
|
safe, fast, productive.
|
|
Pick three.";
|
|
|
|
assert_eq!(
|
|
vec!["safe, fast, productive."],
|
|
search_case_sensitive(pattern, contents)
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn case_insensitive() {
|
|
let pattern = "duct";
|
|
let contents = "\
|
|
Rust:
|
|
safe, fast, productive.
|
|
Pick three.";
|
|
|
|
assert_eq!(
|
|
vec!["safe, fast, productive."],
|
|
search_case_insensitive(pattern, contents)
|
|
);
|
|
}
|
|
}
|