Skip to main content

apif_parser/
assertions.rs

1pub fn strip_assertion_comments(line: &str) -> Option<String> {
2    let mut out = String::with_capacity(line.len());
3    let mut chars = line.chars().peekable();
4    let mut in_string = false;
5    let mut quote_char = '\0';
6    let mut escaped = false;
7    let mut saw_non_whitespace = false;
8
9    while let Some(ch) = chars.next() {
10        if in_string {
11            out.push(ch);
12            if escaped {
13                escaped = false;
14                continue;
15            }
16            if ch == '\\' {
17                escaped = true;
18                continue;
19            }
20            if ch == quote_char {
21                in_string = false;
22                quote_char = '\0';
23            }
24            continue;
25        }
26
27        if ch == '"' || ch == '\'' {
28            in_string = true;
29            quote_char = ch;
30            out.push(ch);
31            saw_non_whitespace = true;
32            continue;
33        }
34
35        if ch == '#' {
36            break;
37        }
38
39        if ch == '/' && chars.next_if_eq(&'/').is_some() {
40            let prev_is_whitespace = out.chars().last().is_none_or(char::is_whitespace);
41            if !saw_non_whitespace || prev_is_whitespace {
42                break;
43            }
44        }
45
46        if !ch.is_whitespace() {
47            saw_non_whitespace = true;
48        }
49        out.push(ch);
50    }
51
52    let trimmed = out.trim();
53    if trimmed.is_empty() {
54        None
55    } else {
56        Some(trimmed.to_string())
57    }
58}
59
60#[cfg(test)]
61mod tests {
62    use super::strip_assertion_comments;
63
64    #[test]
65    fn test_strips_full_line_double_slash_comments() {
66        assert_eq!(strip_assertion_comments("// comment"), None);
67        assert_eq!(strip_assertion_comments("   // comment"), None);
68    }
69
70    #[test]
71    fn test_strips_inline_comments() {
72        assert_eq!(
73            strip_assertion_comments("@elapsed_ms() >= 10 // startup delay"),
74            Some("@elapsed_ms() >= 10".to_string())
75        );
76        assert_eq!(
77            strip_assertion_comments("@scope.message_count() == 2 # two messages"),
78            Some("@scope.message_count() == 2".to_string())
79        );
80    }
81
82    #[test]
83    fn test_keeps_double_slash_inside_string() {
84        assert_eq!(
85            strip_assertion_comments("@regex(.url, \"^https://example.com\")"),
86            Some("@regex(.url, \"^https://example.com\")".to_string())
87        );
88    }
89}