fluent_syntax/parser/
comment.rs

1use super::{core::Parser, core::Result, Slice};
2use crate::ast;
3
4#[derive(Clone, Copy, Debug, PartialEq)]
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_eol() {
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_eol() {
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}