plantuml_parser/dsl/line/
block_comment_close.rs1use crate::{ParseContainer, ParseResult, wr};
2use nom::Parser;
3use nom::branch::alt;
4use nom::bytes::complete::{tag, take_until};
5use nom::character::complete::{line_ending, not_line_ending, space0};
6use nom::combinator::{eof, map};
7use nom::multi::many1;
8
9#[derive(Clone, Debug)]
28pub struct BlockCommentCloseLine;
29
30impl BlockCommentCloseLine {
31 pub fn parse(input: ParseContainer) -> ParseResult<Self> {
33 let (_, parsed_line) = map(
35 (wr!(not_line_ending), alt((wr!(eof), wr!(line_ending)))),
36 |(line, end)| (&[line, end]).into(),
37 )
38 .parse(input.clone())?;
39
40 let (_, parsed): (_, ParseContainer) = map(
41 (
42 many1((wr!(take_until("'/")), wr!(tag("'/")))),
43 wr!(space0),
44 alt((wr!(eof), wr!(line_ending))),
45 ),
46 |(v, sp, end)| {
47 v.into_iter()
48 .flat_map(|(a1, a2)| vec![a1, a2])
49 .chain([sp, end])
50 .collect::<Vec<_>>()
51 .into()
52 },
53 )
54 .parse(parsed_line)?;
55
56 let rest = input.split_at(parsed.len()).0;
57
58 Ok((rest, (parsed, Self)))
59 }
60}
61
62#[cfg(test)]
63mod tests {
64 use super::*;
65
66 #[test]
67 fn test_parse() -> anyhow::Result<()> {
68 let testdata = [
69 "'/",
70 "'/\n",
71 "'/\t ",
72 "'/ \t \n",
73 "end '/ ",
74 "end '/ \n",
75 "end '/ '/",
76 "end '/ '/\n",
77 "end '/ '/ '/",
78 "end '/ '/ '/\n",
79 ];
80
81 for testdata in testdata.into_iter() {
82 println!("testdata = {testdata:?}");
83
84 let (rest, (parsed, _)) = BlockCommentCloseLine::parse(testdata.into())?;
85 assert_eq!(rest, "");
86 assert_eq!(parsed, testdata);
87 }
88
89 Ok(())
90 }
91
92 #[test]
93 fn test_failed() -> anyhow::Result<()> {
94 let testdata = [
95 "",
97 "\n'/",
99 "\n'/ \t ",
100 "\n '/ \t ",
101 "\n end '/",
102 "\n end '/ \t ",
103 " \n end '/ \t ",
104 ];
105
106 for testdata in testdata.into_iter() {
107 println!("testdata = {testdata:?}");
108
109 let result = BlockCommentCloseLine::parse(testdata.into());
110 assert!(result.is_err());
111 }
112
113 Ok(())
114 }
115}