A small, idiomatic Rust implementation of a simplified grep-style CLI and library.
This repository contains a tiny command-line program (and library) that searches for a query string inside a file and prints matching lines. It demonstrates basic Rust CLI patterns, error handling, and unit testing.
- Features
- Quick start
- CLI usage
- Environment variables
- Library usage
- Examples
- Testing
- Development notes
- Contributing
- License
- Simple, dependency-free Rust implementation
- Case-sensitive and case-insensitive search modes
- Exposes search functions in the
minigrepcrate for reuse in other Rust code
Prerequisites:
- Rust and Cargo installed (https://www.rust-lang.org/tools/install)
Build and run from the repository root:
PowerShell (Windows):
# Build in debug mode
cargo build
# Run the CLI: cargo will pass remaining arguments to the program
cargo run -- <query> <file_path>Or build a release binary:
cargo build --release
.
# Executable is in target\release\minigrep.exeBasic usage:
minigrep <query> <file_path>
- query: the substring to search for
- file_path: path to the file to search
Exit codes:
- 0 on success
- non-zero if there was an error reading the arguments or file
The CLI supports one environment variable to control case sensitivity:
IGNORE_CASE— if this environment variable is set (to any value), the search is performed case-insensitively. By default, the search is case-sensitive.
PowerShell example (enable case-insensitive search in the current session):
$env:IGNORE_CASE = "1"
cargo run -- rUsT poem.txt
# Remove variable from session if desired
Remove-Item Env:\IGNORE_CASEThe crate exposes two functions in src/lib.rs that are useful when embedding the search logic into other Rust programs:
minigrep::search(query: &str, contents: &str) -> Vec<&str>— case-sensitive searchminigrep::search_case_insensitive(query: &str, contents: &str) -> Vec<&str>— case-insensitive search
Example (using the crate as a local dependency or from path):
use minigrep::search;
fn main() {
let text = "Rust:\nsafe, fast, productive.";
let matches = search("duct", text);
assert_eq!(matches, vec!["safe, fast, productive."]);
}Assuming the included poem.txt file is in the repository root:
PowerShell (case-sensitive):
cargo run -- frog poem.txtPowerShell (case-insensitive):
$env:IGNORE_CASE = "1"
cargo run -- rUsT poem.txtSample output (case-insensitive search for rUsT):
Rust:
Trust me.
Run unit tests with:
cargo testThe repository contains unit tests for both case-sensitive and case-insensitive search functions in src/lib.rs.
- CLI argument parsing and config are implemented in
src/main.rs(theConfigstruct andConfig::build). - The
runfunction reads the file and delegates to the appropriate search function based on theIGNORE_CASEenvironment variable.
Contributions are welcome. Please open an issue or submit a pull request with a clear description of the change.
Ideas for follow-ups:
- Add regex support
- Add recursive directory search
- Add colored output and line numbers
No license is specified in Cargo.toml. If you plan to reuse or publish this code, consider adding a license field to Cargo.toml (for example, MIT or Apache-2.0) and including a corresponding LICENSE file.
If anything in this README should be expanded (examples, tests, formatting), tell me what you'd like and I can add it.