1 use super::{Parser, Result, Slice};
2 use crate::ast;
3 
4 #[derive(Debug, PartialEq, Clone, Copy)]
5 pub(super) enum Level {
6     None = 0,
7     Regular = 1,
8     Group = 2,
9     Resource = 3,
10 }
11 
12 impl<'s, S> Parser<S>
13 where
14     S: Slice<'s>,
15 {
get_comment(&mut self) -> Result<(ast::Comment<S>, Level)>16     pub(super) fn get_comment(&mut self) -> Result<(ast::Comment<S>, Level)> {
17         let mut level = Level::None;
18         let mut content = vec![];
19 
20         while self.ptr < self.length {
21             let line_level = self.get_comment_level();
22             if line_level == Level::None {
23                 self.ptr -= 1;
24                 break;
25             } else if level != Level::None && line_level != level {
26                 self.ptr -= line_level as usize;
27                 break;
28             }
29 
30             level = line_level;
31 
32             if self.ptr == self.length {
33                 break;
34             } else if self.is_current_byte(b'\n') {
35                 content.push(self.get_comment_line()?);
36             } else {
37                 if let Err(e) = self.expect_byte(b' ') {
38                     if content.is_empty() {
39                         return Err(e);
40                     } else {
41                         self.ptr -= line_level as usize;
42                         break;
43                     }
44                 }
45                 content.push(self.get_comment_line()?);
46             }
47             self.skip_eol();
48         }
49 
50         Ok((ast::Comment { content }, level))
51     }
52 
get_comment_level(&mut self) -> Level53     fn get_comment_level(&mut self) -> Level {
54         let mut chars = 0;
55 
56         for _ in 0..3 {
57             if self.take_byte_if(b'#') {
58                 chars += 1;
59             }
60         }
61 
62         match chars {
63             0 => Level::None,
64             1 => Level::Regular,
65             2 => Level::Group,
66             3 => Level::Resource,
67             _ => unreachable!(),
68         }
69     }
70 
get_comment_line(&mut self) -> Result<S>71     fn get_comment_line(&mut self) -> Result<S> {
72         let start_pos = self.ptr;
73 
74         while self.ptr < self.length && !self.is_eol() {
75             self.ptr += 1;
76         }
77 
78         Ok(self.source.slice(start_pos..self.ptr))
79     }
80 }
81