plantuml_parser/dsl/block/
block_comment.rs1use crate::PlantUmlLine;
2use crate::{ParseContainer, ParseError, ParseResult};
3use std::sync::Arc;
4
5#[derive(Clone, Debug)]
36pub struct BlockComment {
37 lines: Vec<Arc<PlantUmlLine>>,
38 completed: bool,
39}
40
41impl BlockComment {
42 pub fn parse(input: ParseContainer) -> ParseResult<Self> {
44 let (mut rest, (_, line)) = PlantUmlLine::parse(input.clone())?;
45
46 if line.block_comment_open().is_none() {
47 return Err(ParseError::fail(input));
48 }
49
50 let mut lines = vec![Arc::new(line)];
51 let mut completed = false;
52
53 loop {
54 let (rest_inner, (_, mut line_inner)) = PlantUmlLine::parse(rest)?;
55
56 rest = rest_inner;
57
58 let is_closed = line_inner.block_comment_close().is_some();
59 if !is_closed {
60 line_inner = line_inner.into_in_comment();
61 }
62
63 lines.push(Arc::new(line_inner));
64
65 if is_closed {
66 completed = true;
67 break;
68 }
69
70 if rest.is_empty() {
71 break;
72 }
73 }
74
75 let parsed = input.split_at(input.len() - rest.len()).1;
76 Ok((rest, (parsed, Self { lines, completed })))
77 }
78
79 pub fn is_completed(&self) -> bool {
81 self.completed
82 }
83
84 pub fn lines(&self) -> &[Arc<PlantUmlLine>] {
86 self.lines.as_slice()
87 }
88}
89
90impl std::fmt::Display for BlockComment {
91 fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
92 for line in self.lines.iter() {
93 line.raw_str().fmt(formatter)?;
94 }
95
96 Ok(())
97 }
98}
99
100#[cfg(test)]
101mod tests {
102 use super::*;
103
104 #[test]
105 fn test_0() -> anyhow::Result<()> {
106 let input = ParseContainer::from(
107 r#"/'
108 comment
109 '/"#,
110 );
111
112 let (rest0, (parsed0, comment)) = BlockComment::parse(input.clone())?;
113 println!("rest0 = {rest0}");
114 println!("parsed0 = {parsed0}");
115 println!("comment = {comment:?}");
116 println!("comment (raw) = {comment}");
117 assert_eq!(rest0, "");
118 assert_eq!(parsed0, input);
119 assert!(comment.is_completed());
120
121 Ok(())
122 }
123
124 #[test]
125 fn test_1() -> anyhow::Result<()> {
126 let input = ParseContainer::from(
127 r#"/' incompleted
128 comment
129 "#,
130 );
131
132 let (rest0, (parsed0, comment)) = BlockComment::parse(input)?;
133 println!("rest0 = {rest0}");
134 println!("parsed0 = {parsed0}");
135 println!("comment = {comment:?}");
136 println!("comment (raw) = {comment}");
137 assert!(!comment.is_completed());
138
139 Ok(())
140 }
141}