hyper_scripter/
extract_msg.rs1const 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
29pub fn extract_env_from_content_help_aware(content: &str) -> impl Iterator<Item = (bool, &str)> {
31 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}