1use super::{core::Parser, core::Result, Slice};
2use crate::ast;
3
4#[derive(Debug, PartialEq, Clone, Copy)]
5pub(super) enum Level {
6 None = 0,
7 Regular = 1,
8 Group = 2,
9 Resource = 3,
10}
11
12impl<'s, S> Parser<S>
13where
14 S: Slice<'s>,
15{
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
53 pub(super) fn skip_comment(&mut self) {
54 loop {
55 while self.ptr < self.length && !self.is_current_byte(b'\n') {
56 self.ptr += 1;
57 }
58 self.ptr += 1;
59 if self.is_current_byte(b'#') {
60 self.ptr += 1;
61 } else {
62 break;
63 }
64 }
65 }
66
67 fn get_comment_level(&mut self) -> Level {
68 if self.take_byte_if(b'#') {
69 if self.take_byte_if(b'#') {
70 if self.take_byte_if(b'#') {
71 return Level::Resource;
72 }
73 return Level::Group;
74 }
75 return Level::Regular;
76 }
77 Level::None
78 }
79
80 fn get_comment_line(&mut self) -> S {
81 let start_pos = self.ptr;
82
83 while !self.is_eol() {
84 self.ptr += 1;
85 }
86
87 self.source.slice(start_pos..self.ptr)
88 }
89}
90