107 lines
2.7 KiB
Rust
Executable File
107 lines
2.7 KiB
Rust
Executable File
use std::error::Error;
|
|
use std::fmt;
|
|
|
|
pub struct Config {
|
|
pub query: String,
|
|
pub filename: String,
|
|
pub sensitive: bool,
|
|
}
|
|
|
|
impl Config {
|
|
pub fn new(args: &[String]) -> Result<Config, &'static str> {
|
|
if args.len() < 2 {
|
|
return Err("args len less then 2");
|
|
}
|
|
let query = args[0].clone();
|
|
let filename = args[1].clone();
|
|
let sensitive = std::env::var("CASE_SENSITIVE").is_ok();
|
|
Ok(Config {
|
|
query,
|
|
filename,
|
|
sensitive,
|
|
})
|
|
}
|
|
}
|
|
|
|
pub struct GrepRet {
|
|
line: i32,
|
|
context: String,
|
|
}
|
|
impl GrepRet {
|
|
fn new(line: i32, context: &str) -> GrepRet {
|
|
GrepRet {
|
|
line,
|
|
context: context.to_string(),
|
|
}
|
|
}
|
|
}
|
|
impl fmt::Display for GrepRet {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
write!(f, "line:{}: {}", self.line, self.context)
|
|
}
|
|
}
|
|
pub fn run(config: &Config) -> Result<Vec<GrepRet>, Box<dyn Error>> {
|
|
let context = std::fs::read_to_string(&config.filename)?;
|
|
if config.sensitive {
|
|
Ok(search_sensitive(&config.query, &context))
|
|
} else {
|
|
Ok(search_insensitive(&config.query, &context))
|
|
}
|
|
}
|
|
|
|
fn search_sensitive(query: &str, context: &String) -> Vec<GrepRet> {
|
|
let mut idx = 0;
|
|
let mut result = Vec::new();
|
|
for line in context.lines() {
|
|
idx += 1;
|
|
if line.contains(query) {
|
|
result.push(GrepRet::new(idx, line));
|
|
}
|
|
}
|
|
result
|
|
}
|
|
|
|
fn search_insensitive(query: &str, context: &String) -> Vec<GrepRet> {
|
|
let mut idx = 0;
|
|
let mut result = Vec::new();
|
|
for line in context.lines() {
|
|
idx += 1;
|
|
let lower = line.to_lowercase();
|
|
if lower.contains(&query.to_lowercase()) {
|
|
result.push(GrepRet::new(idx, line));
|
|
}
|
|
}
|
|
result
|
|
}
|
|
|
|
#[cfg(test)]
|
|
pub mod test {
|
|
use super::*;
|
|
#[test]
|
|
fn grep_new1() {
|
|
let line = 10;
|
|
let context = "zzz";
|
|
let grep_ret = GrepRet::new(line, context);
|
|
assert_eq!(line, grep_ret.line);
|
|
assert_eq!(context, grep_ret.context);
|
|
}
|
|
#[test]
|
|
fn grep_new2() {
|
|
let line = 10;
|
|
let context = "zzz";
|
|
let grep_ret = GrepRet::new(line, context);
|
|
assert_ne!(!line, grep_ret.line);
|
|
assert_eq!(context, grep_ret.context);
|
|
}
|
|
|
|
#[test]
|
|
#[ignore] // cargo test -- --ignored
|
|
fn grep_new3() {
|
|
let line = 10;
|
|
let context = "zzz";
|
|
let grep_ret = GrepRet::new(line, context);
|
|
assert_ne!(!line, grep_ret.line);
|
|
assert_eq!(context, grep_ret.context);
|
|
}
|
|
}
|