use std::{env, fs::File, io::{self, BufRead, BufReader, Write}};
use regex::Regex;
pub fn start_search() {
let args: Vec<String> = env::args().collect();
if args.len() < 4 {
eprintln!("Usage: cargo run -- <mode> <search_string> <file_path> [output_file] [--ignore-case]");
return;
}
let mode = &args[1];
let query = &args[2];
let file_path = &args[3];
let mut output_file = None;
let mut ignore_case = false;
for arg in &args[4..] {
if arg == "--ignore-case" {
ignore_case = true;
} else if output_file.is_none() {
output_file = Some(arg.as_str());
}
}
println!("Performing '{}' mode search for '{}' in file '{}'", mode, query, file_path);
if output_file.is_none() {
println!("No output file specified. Results will be printed to the console.");
}
if let Err(e) = match mode.as_str() {
"search" => search_in_file(file_path, query, output_file, ignore_case, false),
"regex" => search_in_file(file_path, query, output_file, ignore_case, true),
_ => {
eprintln!("Invalid mode '{}'. Use 'search' or 'regex'.", mode);
return;
}
} {
eprintln!("Error: {}", e);
}
}
fn search_in_file(
file_path: &str,
query: &str,
output_file: Option<&str>,
ignore_case: bool,
is_regex: bool,
) -> io::Result<()> {
let file = File::open(file_path)?;
let reader = BufReader::new(file);
let mut writer: Box<dyn Write> = match output_file {
Some(output_path) => Box::new(File::create(output_path)?),
None => Box::new(io::stdout()),
};
let mut found_match = false;
for (line_number, line) in reader.lines().enumerate() {
let line = line?;
let match_found = if is_regex {
let regex = if ignore_case {
Regex::new(&format!("(?i){}", query))
} else {
Regex::new(query)
};
match regex {
Ok(re) => re.is_match(&line),
Err(_) => {
eprintln!("Invalid regex pattern '{}'", query);
return Ok(());
}
}
} else {
if ignore_case {
line.to_lowercase().contains(&query.to_lowercase())
} else {
line.contains(query)
}
};
if match_found {
writeln!(writer, "Line {}: {}", line_number + 1, line)?;
found_match = true; }
}
if !found_match {
eprintln!("No matches found for '{}' in file '{}'", query, file_path);
}
Ok(())
}