diff --git a/poem.txt b/poem.txt new file mode 100644 index 0000000..8707527 --- /dev/null +++ b/poem.txt @@ -0,0 +1,9 @@ +I'm nobody! Who are you? +Are you nobody, too? +Then there's a pair of us - don't tell! +They'd banish us, you know. + +How dreary to be somebody! +How public, like a frog +To tell your name the livelong day +To an admiring bog! diff --git a/src/input_output.rs b/src/input_output.rs new file mode 100644 index 0000000..6062fe9 --- /dev/null +++ b/src/input_output.rs @@ -0,0 +1,147 @@ +use std::env; +use std::fs; + +// struct to query a search into a file +struct Config { + query: String, // key + file_name: String, // file to search from + ignore_case: bool, // case sensitive search +} + +fn main() { + let user_arg: Vec = env::args().collect(); + let config = Config::build(user_arg); + run(config); +} + +/// fn to run query search output +fn run(config: Result) { + match config { + Ok(data) => { + let content = fs::read_to_string(&data.file_name).expect("data not foundd"); + + //println!("env arg {}", data); + let result = if data.ignore_case { + case_sensitive_query_search(data.query, &content) + } else { + query_search(data.query, &content) + }; + match result { + Ok(value) => { + println!("{:#?}", value); + } + Err(e) => { + println!("{e}") + } + } + } + Err(error) => { + println!("{error}") + } + } +} + +impl Config { + fn build(user_arg: Vec) -> Result { + if user_arg.len() < 3 { + Err("argument not complete".to_string()) + } else { + let query = &user_arg[1]; + let file_name = &user_arg[2]; + + // to run a case sensitive search run IGNORE_CASE=1 cargo run -- to poem.txt + // if IGNORE_CASE exist in env the variable will be true else false + let ignore_case = env::var("IGNORE_CASE").is_ok(); + + Ok(Config { + query: query.clone(), + file_name: file_name.clone(), + ignore_case, + }) + } + } +} + +// non case sensitive search +fn query_search<'a>(key: String, content: &'a str) -> Result, String> { + let mut storage = Vec::new(); + if content.contains(&key) { + for line in content.lines() { + if line.contains(&key) { + storage.push(line); + } + } + Ok(storage) + } else { + Err("Error: key does not exist".to_string()) + } +} + +// case sensitive search +fn case_sensitive_query_search<'a>(key: String, content: &'a str) -> Result, String> { + let mut storage = Vec::new(); + // println!("{} the key {}",content.to_lowercase(),&key.to_lowercase()); + if content.to_lowercase().contains(&key.to_lowercase()) { + for line in content.lines() { + if line.to_lowercase().contains(&key.to_lowercase()) { + storage.push(line); + } + } + Ok(storage) + } else { + //println!("hello"); + Err("Error: key does not exist".to_string()) + } +} + +#[cfg(test)] +mod test { + use super::*; + #[test] + + fn test_query_search() { + let query = "duct"; + let contents = "\ + Rust: + safe, fast, productive. + Pick three."; + let search = query_search(query.to_string(), contents).unwrap(); + assert_eq!(vec!["safe, fast, productive."], search) + } + + #[test] + + fn test_query_search_fail() { + let query = "to"; + let contents = "\ + Rust: + safe, fast, productive. + Pick three."; + let search = query_search(query.to_string(), contents); + assert_eq!(Err("Error: key does not exist".to_string()), search) + } + + #[test] + + fn test_case_sensitive_query_search() { + let query = "Duct"; + let contents = "\ +Rust: +safe, fast, productive. +Pick three."; + let search = case_sensitive_query_search(query.to_string(), contents).unwrap(); + assert_eq!(vec!["safe, fast, productive."], search) + } + + #[test] + + fn test_case_sensitive_query_search_fail() { + let query = "india"; + let contents = "\ +Rust: +safe, fast, productive. +Pick three."; + let search = case_sensitive_query_search(query.to_string(), contents); + assert_eq!(Err("Error: key does not exist".to_string()), search) + } +} diff --git a/src/main.rs b/src/main.rs index 853f2da..7fb6b46 100644 --- a/src/main.rs +++ b/src/main.rs @@ -13,6 +13,7 @@ mod calculator; mod collections; mod constructor; mod float; +mod input_output; mod signed; mod string; mod todo;