1use std::error::Error;
5use std::{env, fs};
6
7pub struct Config{
17 pub consulta: String,
18 pub ruta: String,
19 pub distinguir: bool,
20}
21
22impl Config{
23 pub fn build(mut args: impl Iterator<Item = String>) -> Result<Config, &'static str>{
36 args.next();
37
38 let consulta = match args.next(){
39 Some(arg) => arg,
40 None => return Err("No se especificó el texto de búsqueda"),
41 };
42 let ruta = match args.next(){
43 Some(arg) => arg,
44 None => return Err("No se especificó la ruta del archivo"),
45 };
46
47 let distinguir = env::var("IGNORE_CASE").is_ok();
48
49 Ok(Config{consulta, ruta, distinguir})
50 }
51}
52
53pub fn run(config: Config) -> Result<(), Box<dyn Error>>{
70 let contenido = fs::read_to_string(config.ruta)?;
71
72 let resultado = if config.distinguir{
73 busqueda(&config.consulta, &contenido)
74 }else{
75 buscar_distinguido(&config.consulta, &contenido)
76 };
77
78 for linea in resultado{
79 println!("{linea}");
80 }
81 Ok(())
82}
83
84fn busqueda<'a>(consulta: &str, contenido: &'a str) -> Vec<&'a str>{
85 contenido
86 .lines()
87 .filter(
88 |linea|
89 linea.contains(consulta)
90 )
91 .collect()
92}
93
94fn buscar_distinguido<'a>(consulta: &str, contenido: &'a str) -> Vec<&'a str>{
95 let consulta = consulta.to_lowercase();
96 contenido
97 .lines()
98 .filter(
99 |linea|
100 linea.to_lowercase().contains(&consulta)
101 )
102 .collect()
103}
104
105#[cfg(test)]
106mod test{
107 use super::*;
108
109 #[test]
110 fn un_resultado() {
111 let consulta = "duct";
112 let contenido = "\
113Rust:
114safe, fast, productive.
115Pick three.";
116
117 assert_eq!(vec!["safe, fast, productive."], busqueda(consulta, contenido));
118 }
119
120 #[test]
121 fn distinguido() {
122 let consulta = "duct";
123 let contenido = "\
124Rust:
125safe, fast, productive.
126Pick three.
127Duct tape.";
128
129 assert_eq!(vec!["safe, fast, productive."], busqueda(consulta, contenido));
130 }
131
132 #[test]
133 fn no_distinguido() {
134 let consulta = "rUsT";
135 let contenido = "\
136Rust:
137safe, fast, productive.
138Pick three.
139Trust me.";
140
141 assert_eq!(vec!["Rust:", "Trust me."], buscar_distinguido(consulta, contenido));
142 }
143}