1use std::{env, fs, process};
2use std::error::Error;
3
4pub fn read_command_line_arg() {
5 let args: Vec<String> = env::args().collect();
6 println!("{:?}", args);
7
8 let config = Config::New(&args).unwrap_or_else(|err| {
9 println!("Problem parsing arguments: {}", err);
10 process::exit(1);
11 });
12
13 if let Err(e) = run(config) {
14 eprintln!("Application error: {}", e);
15 process::exit(1);
16 }
17
18}
19
20pub fn read_command_line_arg_two() {
21 let config = Config::New_two(env::args()).unwrap_or_else(|err| {
22 println!("Problem parsing arguments: {}", err);
23 process::exit(1);
24 });
25
26 if let Err(e) = run(config) {
27 eprintln!("Application error: {}", e);
28 process::exit(1);
29 }
30
31}
32
33struct Config {
34 query: String,
35 fileName: String,
36 case_insensitive: bool,
37}
38
39impl Config {
40 fn New(args: &[String]) -> Result<Config, &'static str> {
41 if args.len() < 3 {
42 return Err("not enough arguments");
43 }
44 let query = args[1].clone();
45 let fileName = args[2].clone();
46 let case_insensitive = env::var("CASE_INSENSITIVE").is_err();
47 Ok(Config {
48 query, fileName, case_insensitive
49 })
50 }
51
52 fn New_two(mut args: std::env::Args) -> Result<Config, &'static str> {
53 if args.len() < 3 {
54 return Err("not enough arguments");
55 }
56 args.next();
57 let query = match args.next() {
58 Some(arg) => arg,
59 None => return Err("Didn't get a query String"),
60 };
61 let fileName = match args.next(){
62 Some(arg) => arg,
63 None => return Err("Didn't get a file name")
64 };
65 let case_insensitive = env::var("CASE_INSENSITIVE").is_err();
66 Ok(Config {
67 query, fileName, case_insensitive
68 })
69 }
70}
71
72fn run(config: Config) -> Result<(), Box<dyn Error>> {
73 let content = fs::read_to_string(config.fileName)?;
74 println!("content value is {}", content);
75 let result = if config.case_insensitive {
76 search(&config.query, &content)
77 } else {
78 search_case_insensitive(&config.query, &content)
79 };
80 for line in result {
81 println!("line : {}", line);
82 }
83 Ok(())
84}
85
86pub fn search<'a> (query: &str, content: &'a str) -> Vec<&'a str> {
87 let mut result = Vec::new();
88 for line in content.lines() {
89 if line.contains(query) {
90 result.push(line);
91 }
92 }
93 result
94}
95
96pub fn search_two<'a> (query: &str, content: &'a str) -> Vec<&'a str> {
97 content.lines().filter(|line| line.contains(query)).collect()
98}
99
100pub fn search_case_insensitive<'a>(query: &str, content: &'a str) -> Vec<&'a str> {
101 let mut result = Vec::new();
102 let query = query.to_lowercase();
103 for line in content.lines() {
104 if line.to_lowercase().contains(&query) {
105 result.push(line);
106 }
107 }
108 result
109}