plantuml_parser/dsl/token/
footer.rs

1use crate::dsl::token::shared::{Comment, Delimiter};
2use crate::{ParseContainer, ParseResult, wr, wr2};
3use nom::Parser;
4use nom::bytes::complete::tag_no_case;
5
6/// A token sequence that is around the footer keyword. (like `"footer EXAMPLE FOOTER"`.)
7///
8/// # Examples
9///
10/// ```
11/// use plantuml_parser::{FooterToken, ParseContainer};
12///
13/// # fn main() -> anyhow::Result<()> {
14/// let input = "footer  EXAMPLE FOOTER   "; /// The last "   " is rest parts
15/// let (rest, (raws, token)) = FooterToken::parse(input.into())?;
16/// let combined_raw: ParseContainer = raws.into();
17/// assert_eq!(rest, "   ");
18/// assert_eq!(combined_raw, "footer  EXAMPLE FOOTER");
19/// assert_eq!(token.footer(), "EXAMPLE FOOTER");
20/// # Ok(())
21/// # }
22/// ```
23#[derive(Clone, Debug)]
24pub struct FooterToken {
25    footer: Comment,
26    delimiter: Delimiter,
27}
28
29impl FooterToken {
30    /// Tries to parse [`FooterToken`]. (e.g. `"footer EXAMPLE FOOTER"`.)
31    pub fn parse(input: ParseContainer) -> ParseResult<Self> {
32        let (rest, (footer_tag, (delimiter_raw, delimiter), (footer_raw, footer))) = (
33            wr!(tag_no_case("footer")),
34            wr2!(Delimiter::parse),
35            wr2!(Comment::parse),
36        )
37            .parse(input)?;
38
39        let ret0 = ParseContainer::from(vec![footer_tag, delimiter_raw, footer_raw]);
40        let ret1 = Self { footer, delimiter };
41
42        Ok((rest, (ret0, ret1)))
43    }
44
45    /// Returns footer's text
46    pub fn footer(&self) -> &str {
47        self.footer.as_str()
48    }
49
50    /// Returns delimiter
51    pub fn delimiter(&self) -> Option<&str> {
52        self.delimiter.delimiter()
53    }
54}
55
56#[cfg(test)]
57mod tests {
58    use super::*;
59
60    #[test]
61    fn test_parse() -> anyhow::Result<()> {
62        let testdata = "footer EXAMPLE FOOTER";
63        let (rest, (parsed, token)) = FooterToken::parse(testdata.into())?;
64        assert_eq!(rest, "");
65        assert_eq!(testdata, parsed);
66        assert_eq!("EXAMPLE FOOTER", token.footer());
67
68        let testdata = "footer EXAMPLE \t FOOTER  \t";
69        let (rest, (parsed, token)) = FooterToken::parse(testdata.into())?;
70        assert_eq!(rest, "  \t");
71        assert_eq!("footer EXAMPLE \t FOOTER", parsed);
72        assert_eq!("EXAMPLE \t FOOTER", token.footer());
73
74        Ok(())
75    }
76
77    #[test]
78    fn test_parse_case_insensitive() -> anyhow::Result<()> {
79        let testdata = "Footer EXAMPLE FOOTER";
80        let (rest, (parsed, token)) = FooterToken::parse(testdata.into())?;
81        assert_eq!(rest, "");
82        assert_eq!(testdata, parsed);
83        assert_eq!("EXAMPLE FOOTER", token.footer());
84
85        let testdata = "FOOTER EXAMPLE FOOTER";
86        let (rest, (parsed, token)) = FooterToken::parse(testdata.into())?;
87        assert_eq!(rest, "");
88        assert_eq!(testdata, parsed);
89        assert_eq!("EXAMPLE FOOTER", token.footer());
90
91        let testdata = "foOter EXAMPLE FOOTER";
92        let (rest, (parsed, token)) = FooterToken::parse(testdata.into())?;
93        assert_eq!(rest, "");
94        assert_eq!(testdata, parsed);
95        assert_eq!("EXAMPLE FOOTER", token.footer());
96
97        Ok(())
98    }
99
100    #[test]
101    fn test_parse_with_delimiter() -> anyhow::Result<()> {
102        let testdata = "footer : EXAMPLE FOOTER";
103        let (rest, (parsed, token)) = FooterToken::parse(testdata.into())?;
104        assert_eq!(rest, "");
105        assert_eq!(testdata, parsed);
106        assert_eq!("EXAMPLE FOOTER", token.footer());
107
108        let testdata = "footer:\t EXAMPLE FOOTER";
109        let (rest, (parsed, token)) = FooterToken::parse(testdata.into())?;
110        assert_eq!(rest, "");
111        assert_eq!(testdata, parsed);
112        assert_eq!("EXAMPLE FOOTER", token.footer());
113
114        let testdata = "footer \t:EXAMPLE FOOTER";
115        let (rest, (parsed, token)) = FooterToken::parse(testdata.into())?;
116        assert_eq!(rest, "");
117        assert_eq!(testdata, parsed);
118        assert_eq!("EXAMPLE FOOTER", token.footer());
119
120        let testdata = "footer:EXAMPLE FOOTER";
121        let (rest, (parsed, token)) = FooterToken::parse(testdata.into())?;
122        assert_eq!(rest, "");
123        assert_eq!(testdata, parsed);
124        assert_eq!("EXAMPLE FOOTER", token.footer());
125
126        Ok(())
127    }
128}