plantuml_parser/dsl/token/
inline_block_comment.rs

1use crate::{ParseContainer, ParseResult, wr};
2use nom::Parser;
3use nom::bytes::complete::{tag, take_until};
4use nom::character::complete::space0;
5
6/// A token sequence that is an inline block comment. (like `"/' comment '/"`. not like `"/' one '/ /' two '/"`)
7///
8/// # Examples
9///
10/// ```
11/// use plantuml_parser::{InlineBlockCommentToken, ParseContainer};
12///
13/// # fn main() -> anyhow::Result<()> {
14/// let input = " /' comment '/  footer  EXAMPLE FOOTER   "; /// The last part of "footer  EXAMPLE FOOTER   " is rest part.
15/// let (rest, (raws, token)) = InlineBlockCommentToken::parse(input.into())?;
16/// let combined_raw: ParseContainer = raws.into();
17/// assert_eq!(rest, "footer  EXAMPLE FOOTER   ");
18/// assert_eq!(combined_raw, " /' comment '/  ");
19/// # Ok(())
20/// # }
21/// ```
22#[derive(Clone, Debug)]
23pub struct InlineBlockCommentToken {
24    comment: ParseContainer,
25}
26
27impl InlineBlockCommentToken {
28    /// Tries to parse [`InlineBlockCommentToken`]
29    pub fn parse(input: ParseContainer) -> ParseResult<Self> {
30        let (rest, parsed) = (
31            wr!(space0),
32            wr!(tag("/'")),
33            wr!(take_until("'/")),
34            wr!(tag("'/")),
35            wr!(space0),
36        )
37            .parse(input)?;
38
39        let parsed = Vec::from(<[ParseContainer; 5]>::from(parsed));
40        let ret = Self {
41            comment: parsed.into(),
42        };
43
44        Ok((rest, (ret.comment.clone(), ret)))
45    }
46
47    pub fn comment(&self) -> &str {
48        self.comment.as_str()
49    }
50}
51
52#[cfg(test)]
53mod tests {
54    use super::*;
55
56    #[test]
57    fn test_parse() -> anyhow::Result<()> {
58        let testdata = [
59            ("/' comment '/   ", ""),
60            ("    /' comment '/", ""),
61            ("  /' comment '/   ", ""),
62            (" /' comment '/ rest ", "rest "),
63            (
64                " /' comment '/  /' comment '/ rest  ",
65                "/' comment '/ rest  ",
66            ),
67        ];
68
69        for (testdata, expected_rest) in testdata.into_iter() {
70            let (rest, (parsed, comment)) = InlineBlockCommentToken::parse(testdata.into())?;
71            assert_eq!(parsed, comment.comment);
72            assert_eq!(rest, expected_rest);
73            assert_eq!(parsed, &testdata[0..testdata.len() - rest.len()]);
74        }
75
76        Ok(())
77    }
78}