Last active
February 17, 2024 13:41
-
-
Save m0hadang/48a98be4c44188b0673859a018fd3f7d to your computer and use it in GitHub Desktop.
rust-sample(main, test, lib)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use std::error::Error; | |
use std::fs; | |
use std::env; | |
pub struct Config { | |
pub query: String, | |
pub filename: String, | |
pub case_sensitive: bool, | |
} | |
impl Config { | |
pub fn new(mut args: std::env::Args) -> Result<Config, &'static str> { | |
args.next();// 프로그램 이름 skip | |
let query = match args.next() { | |
Some(arg) => arg, | |
None => return Err("검색어를 지정해야 합니다."), | |
}; | |
let filename = match args.next() { | |
Some(arg) => arg, | |
None => return Err("파일명을 지정해야 합니다."), | |
}; | |
let case_sensitive = env::var("CASE_INSENSITIVE").is_err(); | |
Ok(Config { query, filename, case_sensitive }) | |
} | |
} | |
pub fn run(config: Config) -> Result<(), Box<dyn Error>> { | |
// 성공하였을 경우 함수 기본 반환 값인 ()를 반환 | |
// 실패하였을 경우 Box<dyn Error> 트레이트 반환 | |
let contents = fs::read_to_string(config.filename)?;// ? : 에러 발생하였을 경우 호출자에게 에러 반환 | |
let results = if config.case_sensitive { | |
search(&config.query, &contents) | |
} else { | |
search_case_insensitive(&config.query, &contents) | |
}; | |
for line in results { | |
println!("{}", line); | |
} | |
Ok(()) | |
} | |
pub fn search<'a>(query: &str, contents: &'a str) -> Vec<&'a str> { | |
//수명 어노테이션 사용하여 인수의 수명이 리턴값의 수명과 연결 되었음을 컴파일러에 알림 | |
//contents 인수는 검색 대상이 되는 모든 텍스트를 저장하고 있으며 | |
//리턴할 값은 그 일부이므로 contents 인수의 수명이 리턴값의 수명과 연결되어야 한다. | |
contents.lines() | |
.filter(|line| line.contains(query)) | |
.collect() | |
} | |
pub fn search_case_insensitive<'a>(query: &str, contents: &'a str) -> Vec<&'a str> { | |
let query = query.to_lowercase();//query : &str -> String | |
let mut results = Vec::new(); | |
for line in contents.lines() { | |
if line.to_lowercase().contains(&query) { // contains 는 문자열 슬라이스를 받는다. | |
results.push(line); | |
} | |
} | |
results | |
} | |
#[cfg(test)] | |
mod test { | |
use super::*; | |
#[test] | |
fn case_sensitive() { | |
let query = "duct"; | |
let contents = "\ | |
Rust: | |
safe, fast, productive. | |
Pick three. | |
Duct tape."; | |
assert_eq!( | |
vec!["safe, fast, productive."], | |
search(query, contents) | |
); | |
} | |
#[test] | |
fn case_insensitive() { | |
let query = "rUsT"; | |
let contents = "\ | |
Rust: | |
safe, fast, productive. | |
Pick three. | |
Trust me."; | |
assert_eq!( | |
vec!["Rust:", "Trust me."], | |
search_case_insensitive(query, contents) | |
); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use std::env; | |
use std::process; | |
use minigrep::Config; | |
fn main() { | |
let config = Config::new(env::args()).unwrap_or_else(|err| { | |
// 반환이 Ok이면 unwrap과 같이 동작함, 즉 Ok 값을 unwrap 하여 결과값을 반환 | |
// 반환이 Err이면 클로저를 이용해 unwrap_or_else에 전달한 익명 함수를 호출 | |
eprintln!("인수를 구문분석하는 동안 오류가 발생했습니다.: {}", err); | |
process::exit(1); | |
}); | |
println!("검색어 : {}", config.query); | |
println!("대상 파일 : {}", config.filename); | |
if let Err(e) = minigrep::run(config) { | |
eprintln!("애플리케이션 에러: {}", e); | |
process::exit(1); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment