Skip to main content

wp_primitives/
comment.rs

1use winnow::ascii::{multispace0, newline, till_line_ending};
2use winnow::combinator::opt;
3use winnow::token::literal;
4use winnow::{ModalResult as WResult, Parser};
5
6#[derive(Debug)]
7enum DslStatus {
8    Comment,
9    Code,
10}
11pub struct CommentParser {}
12impl Default for CommentParser {
13    fn default() -> Self {
14        Self::new()
15    }
16}
17
18impl CommentParser {
19    pub fn new() -> Self {
20        CommentParser {}
21    }
22    pub fn ignore_comment(input: &mut &str) -> WResult<String> {
23        let mut status = DslStatus::Code;
24        let mut out = String::new();
25        while !input.is_empty() {
26            match status {
27                DslStatus::Code => {
28                    multispace0.parse_next(input)?;
29                    let long_comment: WResult<&str> = literal("/*").parse_next(input);
30                    if long_comment.is_ok() {
31                        status = DslStatus::Comment;
32                        continue;
33                    }
34                    let short_comment: WResult<&str> = literal("//").parse_next(input);
35                    if short_comment.is_ok() {
36                        let _ = till_line_ending.parse_next(input)?;
37                        continue;
38                    }
39                    let code = till_line_ending.parse_next(input)?;
40                    out += code;
41                    if opt(newline).parse_next(input)?.is_some() {
42                        out += "\n";
43                    }
44                    continue;
45                }
46
47                DslStatus::Comment => {
48                    multispace0.parse_next(input)?;
49                    let is_end: WResult<&str> = literal("*/").parse_next(input);
50                    if is_end.is_ok() {
51                        status = DslStatus::Code;
52                        continue;
53                    }
54                    let _ = till_line_ending.parse_next(input)?;
55                    opt(newline).parse_next(input)?;
56                }
57            }
58        }
59        Ok(out)
60    }
61}
62#[cfg(test)]
63mod tests {
64    use super::*;
65
66    #[test]
67    fn test_comment() {
68        let mut code = r#"
69        a=1;
70         //b=1;
71           /*
72        c=1;
73        d=1;
74        */
75        x=1;
76        "#;
77
78        let p_code = CommentParser::ignore_comment(&mut code).expect("ignore comment fail");
79        println!("{}", p_code)
80    }
81}