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