Add mini_grep: like-grep util for terminal

This commit is contained in:
Kirill Samoylenkov 2025-10-11 20:57:40 +05:00
parent 49bd0744b8
commit 996b3d64ac
2 changed files with 117 additions and 1 deletions

101
mini_grep/src/lib.rs Normal file
View file

@ -0,0 +1,101 @@
use std::env;
use std::error::Error;
use std::fs;
pub fn run(config: Config) -> Result<(), Box<dyn Error>> {
let contents = fs::read_to_string(&config.file_name)?;
let results = if config.case_sensitive {
search(&config.query, &contents)
} else {
search_case_insensitive(&config.query, &contents)
};
if results.len() == 0 {
eprintln!("Can't find anything.");
}
for line in results {
println!("{}", line);
}
Ok(())
}
pub struct Config {
pub query: String,
pub file_name: String,
pub case_sensitive: bool,
}
impl Config {
pub fn new(args: &[String]) -> Result<Config, &str> {
if args.len() < 3 {
return Err("No enoght arguments!");
}
let query = args[1].clone();
let file_name = args[2].clone();
let case_sensitive = env::var("CASE_SENSITIVE").is_err();
Ok(Config {
query: query,
file_name: file_name,
case_sensitive: case_sensitive,
})
}
}
pub 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
}
pub fn search_case_insensitive<'a>(query: &str, contents: &'a str) -> Vec<&'a str> {
let mut results = Vec::new();
for line in contents.lines() {
if line.to_lowercase().contains(&query.to_lowercase()) {
results.push(line);
}
}
results
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn one_result() {
let query = "duct";
let contents = "\
Rust:
safe, fast, productive.
Pick three.";
assert_eq!(vec!["safe, fast, productive."], search(query, contents));
}
#[test]
fn case_insensitive() {
let query = "rUsT";
let contents = "\
Rust:
safe, fast, productive.
Trust me.";
assert_eq!(
vec!["Rust:", "Trust me."],
search_case_insensitive(query, contents)
);
}
}

View file

@ -1,3 +1,18 @@
use std::env;
use std::process;
use mini_grep::Config;
fn main() {
println!("Hello, world!");
let args: Vec<String> = env::args().collect();
let config = Config::new(&args).unwrap_or_else(|err| {
eprintln!("Problem parsing arguments: {}", err);
process::exit(1);
});
if let Err(e) = mini_grep::run(config) {
eprintln!("Application error: {}", e);
process::exit(1);
}
}