Skip to main content

sp_grep/
lib.rs

1//! # My Crate
2//! * 일부 연산을 더 쉽게 실행하기 위한 유틸리티 모음
3/// 주어진 숫자에 1을 더한다.
4//ㄴ
5
6
7use std::fs;
8use std::error::Error;
9
10pub struct Config {
11    query: String,
12    filename: String
13}
14
15
16impl Config {
17    /// cloning is more Inefficient than  save Reference data
18    /// because, arg's OW not parse config
19    /// but, LT manage is more easy
20    /// ```
21    /// let query = args[1].clone();
22    /// let filename = args[2].clone();
23    /// ```    
24    /// ` = LT variable
25    ///   static = LT is until the end of program
26    pub fn new(mut args: std::env::Args) -> Result<Config, &'static str>  {
27        args.next(); // args[0] is bin file name
28
29        let query = match args.next() {
30            Some(arg) => arg,
31            None => return Err(" Args is not at all ")
32        };
33
34        let filename = match args.next() {
35            Some(arg) => arg,
36            None => return Err(" Insufficient(불만족) Num Of Arg")
37        };
38        Ok(Config{ query, filename })
39    }
40}
41
42
43/* 
44    1. Box(dyn Error) from Error Trait>
45        Return Various Error at Unexpected
46    2. ? operator return Error instead panic from expect(func)
47
48*/ 
49pub fn run(config: Config) -> Result<(), Box<dyn Error>> {
50    let contents = fs::read_to_string(config.filename)?;
51
52    for line in search(&config.query, &contents) {
53        println!("Matching \n Result: {}", line)
54    }
55    
56    Ok(())
57}
58
59
60// configure as $ cargo test
61#[cfg(test)]
62mod test {
63    use super::*; // import from ../(super)
64
65    #[test]
66    fn one_result() {
67        let query = "good";
68        let contents = "\
69        Rust is Good.. ><
70        hahaha    
71        ";
72
73        assert_eq!(
74            vec!["Rust is Good.. ><"],
75            search(query, contents)
76        );
77    }
78}
79
80// 'a : LT variable
81// contents is must connect return LT
82// contents 는 빌려온 데이터다. 그리고 수명이 이후로도 지속되어야 한다.
83pub fn search<'a>(query: &str, contents: &'a str) -> Vec<&'a str> {
84    // to_lowercase is create new String
85    // shadowing and query become String(heap)(Clone) not str(string slice)
86    // but contains accept only str
87    let query = query;
88    // iter by each line
89    contents.lines() // return iterator
90        .filter(|line| line.contains(query))
91        .collect() // Re assembly (재조립 Array)
92}