hyper_scripter/
extract_msg.rs

1const HELP_KEY: &str = "[HS_HELP]:";
2const ENV_KEY: &str = "[HS_ENV]:";
3const ENV_HELP_KEY: &str = "[HS_ENV_HELP]:";
4
5pub struct Iter<'a, 'b> {
6    content: &'a str,
7    key: &'b str,
8}
9impl<'a, 'b> Iterator for Iter<'a, 'b> {
10    type Item = &'a str;
11    fn next(&mut self) -> Option<Self::Item> {
12        if let Some(pos) = self.content.find(self.key) {
13            let content = &self.content[pos..];
14            let new_line_pos = content.find('\n').unwrap_or_else(|| content.len());
15            let ans = &content[self.key.len()..new_line_pos];
16
17            self.content = &content[new_line_pos..];
18            Some(ans)
19        } else {
20            None
21        }
22    }
23}
24
25pub fn extract_env_from_content(content: &str) -> impl Iterator<Item = &str> {
26    extract_env_from_content_help_aware(content).map(|(_, s)| s)
27}
28
29/// 第一個布林值為真代表 HS_ENV,為假代表 HS_ENV_HELP
30pub fn extract_env_from_content_help_aware(content: &str) -> impl Iterator<Item = (bool, &str)> {
31    // TODO: avoid traversing twice
32    let env_iter = extract_msg_from_content(content, ENV_KEY).map(|s| (true, s));
33    let env_help_iter = extract_msg_from_content(content, ENV_HELP_KEY).map(|s| (false, s));
34    env_iter.chain(env_help_iter).filter_map(|(b, s)| {
35        let s = s.trim();
36        if s.is_empty() {
37            None
38        } else {
39            Some((b, s))
40        }
41    })
42}
43
44pub fn extract_help_from_content(content: &str) -> impl Iterator<Item = &str> {
45    fn trim_first_white(s: &str) -> &str {
46        if let Some(s) = s.strip_prefix(' ') {
47            s
48        } else {
49            s
50        }
51    }
52    extract_msg_from_content(content, HELP_KEY).map(|s| trim_first_white(s))
53}
54
55fn extract_msg_from_content<'a, 'b>(content: &'a str, key: &'b str) -> Iter<'a, 'b> {
56    Iter { content, key }
57}
58
59#[cfg(test)]
60mod test {
61    use super::*;
62    fn extract_help(content: &str, long: bool) -> Vec<&str> {
63        let iter = extract_help_from_content(content);
64        if long {
65            iter.collect()
66        } else {
67            iter.take(1).collect()
68        }
69    }
70
71    #[test]
72    fn test_extract_help() {
73        let content = "
74        // 不要解析我
75        // [HS_HELP]:   解析我吧  
76
77        // [HS_NOHELP]: 不要解析我QQ
78        // [HS_HELP]:
79        fn this_is_a_test() -> bool {}
80
81        # [HS_HELP]: 解析我吧,雖然我是個失敗的註解
82
83        //  前面有些 垃圾[HS_HELP]:我是最後一行";
84        let short = extract_help(content, false);
85        let long = extract_help(content, true);
86        assert_eq!(short, vec!["  解析我吧  "]);
87        assert_eq!(
88            long,
89            vec![
90                "  解析我吧  ",
91                "",
92                "解析我吧,雖然我是個失敗的註解",
93                "我是最後一行"
94            ]
95        );
96
97        let appended = format!("{}\n 真.最後一行", content);
98        let short2 = extract_help(&appended, false);
99        let long2 = extract_help(&appended, true);
100        assert_eq!(short, short2);
101        assert_eq!(long, long2);
102    }
103    #[test]
104    fn test_extract_empty() {
105        let content = "
106        // 不要解析我
107        fn this_is_a_test() -> bool {}
108
109        // [HS_HOLP]:我是最後一行,還拼錯字…";
110        let short = extract_help(content, false);
111        let long = extract_help(content, true);
112        assert_eq!(short.len(), 0);
113        assert_eq!(long.len(), 0);
114    }
115    #[test]
116    fn test_extract_env() {
117        let content = "
118        [HS_ENV_HELP]: env_help1
119        [HS_ENV]: env1
120        [HS_ENV]: env2
121        [HS_ENV_HELP]: env_help2
122        [HS_ENV_HELP]: env_help3
123        [HS_ENV]: env3
124        [HS_ENV_HELP]: env_help4
125        ";
126        let mut v: Vec<_> = extract_env_from_content_help_aware(content).collect();
127        v.sort();
128        assert_eq!(
129            v,
130            vec![
131                (false, "env_help1"),
132                (false, "env_help2"),
133                (false, "env_help3"),
134                (false, "env_help4"),
135                (true, "env1"),
136                (true, "env2"),
137                (true, "env3"),
138            ]
139        );
140    }
141}