Actually just three programming languages in a trenchcoat
at string-repr-callable 50 lines 1.7 kB view raw
1use crate::Parser; 2use trilogy_scanner::Token; 3use trilogy_scanner::TokenType::{self, DocInner, DocOuter}; 4 5/// A documentation comment, either inner or outer. 6/// 7/// ```trilogy 8/// ## Hello this is a doc comment. 9/// ## It may be multiple lines long. 10/// ``` 11#[derive(Clone, Debug, Spanned, PrettyPrintSExpr)] 12pub struct Documentation { 13 pub tokens: Vec<Token>, 14} 15 16impl Documentation { 17 fn parse(parser: &mut Parser, token_type: TokenType) -> Option<Self> { 18 let mut tokens = vec![]; 19 20 while let Ok(token) = parser.expect(token_type) { 21 tokens.push(token); 22 } 23 if tokens.is_empty() { 24 return None; 25 } 26 27 Some(Self { tokens }) 28 } 29 30 pub(crate) fn parse_inner(parser: &mut Parser) -> Option<Self> { 31 Self::parse(parser, DocInner) 32 } 33 34 pub(crate) fn parse_outer(parser: &mut Parser) -> Option<Self> { 35 Self::parse(parser, DocOuter) 36 } 37} 38 39#[cfg(test)] 40mod test { 41 use super::*; 42 43 test_parse!(documentation_inner: "#! hello\n" => Documentation::parse_inner => "(Documentation _)"); 44 test_parse!(documentation_inner_multiline: "#! hello\n#! world\n" => Documentation::parse_inner => "(Documentation _)"); 45 test_parse!(documentation_inner_gaps: "#! hello\n\n#! world\n" => Documentation::parse_inner => "(Documentation _)"); 46 47 test_parse!(documentation_outer: "## hello\n" => Documentation::parse_outer => "(Documentation _)"); 48 test_parse!(documentation_outer_multiline: "## hello\n## world\n" => Documentation::parse_outer => "(Documentation _)"); 49 test_parse!(documentation_outer_gaps: "## hello\n\n## world\n" => Documentation::parse_outer => "(Documentation _)"); 50}