plantuml_parser/dsl/line/
end.rs1use crate::dsl::line::LineWithComment;
2use crate::{InlineBlockCommentToken, ParseContainer, ParseResult, wr};
3use nom::bytes::complete::tag;
4use nom::character::complete::{alpha1, space0};
5use nom::combinator::map;
6use nom::{IResult, Parser};
7
8#[derive(Clone, Debug)]
26pub struct EndLine {
27 diagram_kind: ParseContainer,
28 ibc: Option<InlineBlockCommentToken>,
29}
30
31impl EndLine {
32 pub fn parse(input: ParseContainer) -> ParseResult<Self> {
34 let (rest, (parsed, lwc)) = LineWithComment::parse(inner_parser, input)?;
35
36 let (diagram_kind, ibc) = lwc.into();
37 let ret = Self { diagram_kind, ibc };
38
39 Ok((rest, (parsed.into(), ret)))
40 }
41
42 pub fn eq_diagram_kind(&self, diagram_kind: &str) -> bool {
43 self.diagram_kind == diagram_kind
44 }
45
46 pub fn inline_block_comment(&self) -> Option<&InlineBlockCommentToken> {
47 self.ibc.as_ref()
48 }
49}
50
51fn inner_parser(
52 input: ParseContainer,
53) -> IResult<ParseContainer, (Vec<ParseContainer>, ParseContainer)> {
54 map(
55 (wr!(space0), wr!(tag("@end")), wr!(alpha1), wr!(space0)),
56 |parsed| {
57 let diagram_kind = parsed.2.clone();
58 let parsed = Vec::from(<[ParseContainer; 4]>::from(parsed));
59 (parsed, diagram_kind)
60 },
61 )
62 .parse(input)
63}
64
65#[cfg(test)]
66mod tests {
67 use super::*;
68
69 #[test]
70 fn test_parse_end_line() -> anyhow::Result<()> {
71 let testdata = [
72 ("@enduml\n", None),
73 (" \t@enduml\n", None),
74 ("@enduml \t\n", None),
75 (" \t@enduml \t\n", None),
76 (" /' comment '/ @enduml \t\n", Some(" /' comment '/ ")),
77 (" @enduml /' comment '/ \n", Some("/' comment '/ ")),
78 ];
79
80 for (testdata, expected_comment) in testdata.into_iter() {
81 println!("try: testdata = {testdata:?}");
82 let (rest, (parsed, EndLine { diagram_kind, ibc })) = EndLine::parse(testdata.into())?;
83 assert_eq!(rest, "");
84 assert_eq!(testdata, parsed);
85 assert_eq!(diagram_kind, "uml");
86 assert_eq!(ibc.as_ref().map(|x| x.comment()), expected_comment);
87 }
88
89 Ok(())
90 }
91}