plantuml_parser/dsl/line/
title.rs

1use crate::TitleToken;
2use crate::dsl::line::LineWithComment;
3use crate::{InlineBlockCommentToken, ParseContainer, ParseResult, wr, wr2};
4use nom::character::complete::space0;
5use nom::combinator::map;
6use nom::{IResult, Parser};
7
8/// A token sequence that is a line containing a [`TitleToken`]. (like `"\ttitle EXAMPLE TITLE  \n"`.)
9///
10/// # Examples
11///
12/// ```
13/// use plantuml_parser::{TitleLine, ParseContainer};
14///
15/// # fn main() -> anyhow::Result<()> {
16/// let input = " title EXAMPLE TITLE\n";
17/// let (rest, (raws, token)) = TitleLine::parse(input.into())?;
18/// let combined_raw: ParseContainer = raws.into();
19/// assert_eq!(rest, "");
20/// assert_eq!(combined_raw, " title EXAMPLE TITLE\n");
21/// assert_eq!(token.title(), "EXAMPLE TITLE");
22/// # Ok(())
23/// # }
24/// ```
25#[derive(Clone, Debug)]
26pub struct TitleLine {
27    token: TitleToken,
28    ibc: Option<InlineBlockCommentToken>,
29}
30
31impl TitleLine {
32    /// Tries to parse [`TitleLine`]. (e.g. `" title EXAMPLE TITLE \n"`.)
33    pub fn parse(input: ParseContainer) -> ParseResult<Self> {
34        let (rest, (parsed, lwc)) = LineWithComment::parse(inner_parser, input)?;
35
36        let (token, ibc) = lwc.into();
37
38        let ret0 = ParseContainer::from(parsed);
39        let ret1 = Self { token, ibc };
40
41        Ok((rest, (ret0, ret1)))
42    }
43
44    pub fn inline_block_comment(&self) -> Option<&InlineBlockCommentToken> {
45        self.ibc.as_ref()
46    }
47}
48
49impl std::ops::Deref for TitleLine {
50    type Target = TitleToken;
51    fn deref(&self) -> &Self::Target {
52        &self.token
53    }
54}
55
56fn inner_parser(
57    input: ParseContainer,
58) -> IResult<ParseContainer, (Vec<ParseContainer>, TitleToken)> {
59    map(
60        (wr!(space0), wr2!(TitleToken::parse), wr!(space0)),
61        |(p0, (p1, token), p2)| (vec![p0, p1, p2], token),
62    )
63    .parse(input)
64}
65
66#[cfg(test)]
67mod tests {
68    use super::*;
69
70    #[test]
71    fn test_parse() -> anyhow::Result<()> {
72        let testdata = [
73            ("title TITLE\n", None),
74            (" \ttitle TITLE\n", None),
75            ("title TITLE \t\n", None),
76            (" \ttitle TITLE \t\n", None),
77            ("Title TITLE\n", None),
78            ("TITLE TITLE\n", None),
79            ("tiTle TITLE\n", None),
80            (" /' comment '/ title TITLE\n", Some(" /' comment '/ ")),
81            ("title TITLE /' comment '/ \n", Some("/' comment '/ ")),
82        ];
83
84        for (testdata, expected_comment) in testdata.into_iter() {
85            let (rest, (parsed, TitleLine { token, ibc })) = TitleLine::parse(testdata.into())?;
86
87            assert_eq!(rest, "");
88            assert_eq!(testdata, parsed);
89            assert_eq!(token.title(), "TITLE");
90            assert_eq!(ibc.as_ref().map(|x| x.comment()), expected_comment);
91        }
92
93        Ok(())
94    }
95}