plantuml_parser/
container.rs1use nom::Input;
2use std::sync::Arc;
3
4#[derive(Clone, Debug)]
8pub struct ParseContainer {
9 raw: Arc<String>,
10 begin: usize,
11 end: usize,
12}
13
14#[derive(thiserror::Error, Debug)]
16#[error("parse error: {0}")]
17pub struct ParseError(#[from] pub(crate) nom::Err<nom::error::Error<ParseContainer>>);
18
19pub type ParseResult<T> = Result<(ParseContainer, (ParseContainer, T)), ParseError>;
21
22impl ParseContainer {
23 pub fn new(raw: Arc<String>) -> Self {
37 let end = raw.len();
38 Self { raw, begin: 0, end }
39 }
40
41 pub fn is_empty(&self) -> bool {
67 self.as_str().is_empty()
68 }
69
70 pub fn len(&self) -> usize {
83 self.as_str().len()
84 }
85
86 pub fn as_str(&self) -> &str {
100 &self.raw[self.begin..self.end]
101 }
102
103 pub fn split_at(&self, mid: usize) -> (Self, Self) {
132 #[rustfmt::skip]
133 assert!(self.len() >= mid, "the `mid` is past the end: len = {}, mid = {}", self.len(), mid);
134
135 let rest = Self {
136 begin: self.begin + mid,
137 ..self.clone()
138 };
139
140 let parsed = Self {
141 end: self.begin + mid,
142 ..self.clone()
143 };
144
145 (rest, parsed)
146 }
147}
148
149impl PartialEq for ParseContainer {
150 fn eq(&self, rhs: &ParseContainer) -> bool {
151 self.as_str() == rhs.as_str()
152 }
153}
154
155impl PartialEq<&str> for ParseContainer {
156 fn eq(&self, rhs: &&str) -> bool {
157 self.as_str() == *rhs
158 }
159}
160
161impl PartialEq<ParseContainer> for &str {
162 fn eq(&self, rhs: &ParseContainer) -> bool {
163 *self == rhs.as_str()
164 }
165}
166
167impl std::borrow::Borrow<str> for ParseContainer {
168 fn borrow(&self) -> &str {
169 self.as_str()
170 }
171}
172
173impl std::fmt::Display for ParseContainer {
174 fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
175 self.as_str().fmt(formatter)
176 }
177}
178
179impl From<&str> for ParseContainer {
180 fn from(s: &str) -> Self {
181 Self::new(Arc::new(s.into()))
182 }
183}
184
185impl From<String> for ParseContainer {
186 fn from(s: String) -> Self {
187 Self::new(Arc::new(s))
188 }
189}
190
191impl From<Vec<ParseContainer>> for ParseContainer {
192 fn from(x: Vec<ParseContainer>) -> Self {
193 x.as_slice().into()
194 }
195}
196
197impl From<&[ParseContainer]> for ParseContainer {
198 fn from(x: &[ParseContainer]) -> Self {
200 if x.is_empty() {
201 return Self::new(Arc::new("".into()));
202 }
203
204 let x0 = x.first().unwrap();
205 let len = x.iter().fold(0, |stack, item| stack + item.len());
206
207 Self {
208 end: x0.begin + len,
209 ..x0.clone()
210 }
211 }
212}
213
214impl<const N: usize> From<&[ParseContainer; N]> for ParseContainer {
215 fn from(x: &[ParseContainer; N]) -> Self {
216 x.as_slice().into()
217 }
218}
219
220impl Input for ParseContainer {
221 type Item = char;
222 type Iter = std::vec::IntoIter<Self::Item>;
223 type IterIndices = std::vec::IntoIter<(usize, Self::Item)>;
224
225 fn input_len(&self) -> usize {
226 self.len()
227 }
228
229 fn take(&self, index: usize) -> Self {
230 let end = self.begin + index;
231 assert!(end <= self.end);
232 Self {
233 end,
234 ..self.clone()
235 }
236 }
237
238 fn take_from(&self, index: usize) -> Self {
239 let begin = self.begin + index;
240 assert!(begin <= self.end);
241 Self {
242 begin,
243 ..self.clone()
244 }
245 }
246
247 fn take_split(&self, index: usize) -> (Self, Self) {
248 self.split_at(index)
249 }
250
251 fn position<P>(&self, predicate: P) -> Option<usize>
252 where
253 P: Fn(Self::Item) -> bool,
254 {
255 self.as_str().find(predicate)
256 }
257
258 fn iter_elements(&self) -> <Self as Input>::Iter {
259 self.as_str().chars().collect::<Vec<_>>().into_iter()
260 }
261
262 fn iter_indices(&self) -> <Self as Input>::IterIndices {
263 self.as_str().char_indices().collect::<Vec<_>>().into_iter()
264 }
265
266 fn slice_index(&self, count: usize) -> Result<usize, nom::Needed> {
267 self.as_str().slice_index(count)
268 }
269}
270
271macro_rules! wr {
273 ($func:expr) => {
274 |input: ParseContainer| {
275 use std::sync::Arc;
276
277 let input_str = input.as_str();
278 let (_rest, parsed) =
279 $func(input_str).map_err(|e: nom::Err<nom::error::Error<&str>>| {
280 e.map_input(|x| ParseContainer::new(Arc::new(x.to_owned())))
281 })?;
282 let (rest, parsed) = input.split_at(parsed.len());
283 Ok((rest, parsed))
284 }
285 };
286}
287pub(crate) use wr;
288
289macro_rules! wr2 {
291 ($func:expr) => {
292 |input: ParseContainer| $func(input).map_err(|e: $crate::ParseError| e.0)
293 };
294}
295pub(crate) use wr2;
296
297impl ParseError {
298 pub fn fail(input: ParseContainer) -> Self {
300 Self(nom::Err::Error(nom::error::Error {
301 input,
302 code: nom::error::ErrorKind::Fail,
303 }))
304 }
305}
306
307#[cfg(test)]
308mod tests {
309 use super::*;
310
311 #[test]
312 fn test() {
313 let (rest0, parsed0) = ParseContainer::from("foobar").split_at(2);
314 println!("rest0 = {rest0}");
315 println!("parsed0 = {parsed0}");
316
317 assert_eq!(rest0, "obar");
318 assert_eq!(rest0.is_empty(), false);
319 assert_eq!(rest0.len(), 4);
320 assert_eq!(rest0.as_str(), "obar");
321 assert_eq!(parsed0, "fo");
322 assert_eq!(parsed0.is_empty(), false);
323 assert_eq!(parsed0.len(), 2);
324 assert_eq!(parsed0.as_str(), "fo");
325
326 let (rest1, parsed1) = rest0.split_at(3);
327 println!("rest1 = {rest1}");
328 println!("parsed1 = {parsed1}");
329
330 assert_eq!(rest1, "r");
331 assert_eq!(rest1.is_empty(), false);
332 assert_eq!(rest1.len(), 1);
333 assert_eq!(rest1.as_str(), "r");
334 assert_eq!(parsed1, "oba");
335 assert_eq!(parsed1.is_empty(), false);
336 assert_eq!(parsed1.len(), 3);
337 assert_eq!(parsed1.as_str(), "oba");
338
339 let (rest2, parsed2) = parsed1.split_at(3);
340 println!("rest2 = {rest2}");
341 println!("parsed2 = {parsed2}");
342
343 assert_eq!(rest2, "");
344 assert_eq!(rest2.is_empty(), true);
345 assert_eq!(rest2.len(), 0);
346 assert_eq!(rest2.as_str(), "");
347 assert_eq!(parsed2, "oba");
348 assert_eq!(parsed2.is_empty(), false);
349 assert_eq!(parsed2.len(), 3);
350 assert_eq!(parsed2.as_str(), "oba");
351
352 assert!(Arc::ptr_eq(&rest0.raw, &rest1.raw));
354 assert!(Arc::ptr_eq(&rest0.raw, &rest2.raw));
355 assert!(Arc::ptr_eq(&rest0.raw, &parsed0.raw));
356 assert!(Arc::ptr_eq(&rest0.raw, &parsed1.raw));
357 assert!(Arc::ptr_eq(&rest0.raw, &parsed2.raw));
358 }
359
360 #[test]
361 fn test_split_at() {
362 let (rest, parsed) = ParseContainer::from("foobar").split_at(3);
363 println!("rest = {rest}");
364 println!("parsed = {parsed}");
365
366 assert_eq!(rest, "bar");
367 assert_eq!(parsed, "foo");
368 }
369
370 #[test]
371 #[should_panic(expected = "the `mid` is past the end: len = 0, mid = 1")]
372 fn test_panic_split_at_0() {
373 ParseContainer::from("").split_at(1);
374 }
375
376 #[test]
377 #[should_panic(expected = "the `mid` is past the end: len = 1, mid = 2")]
378 fn test_panic_split_at_1() {
379 let (_rest, parsed) = ParseContainer::from("test").split_at(1);
380 println!("parsed = {parsed}");
381 parsed.split_at(1); parsed.split_at(2);
383 }
384
385 #[test]
386 #[should_panic(expected = "the `mid` is past the end: len = 3, mid = 4")]
387 fn test_panic_split_at_2() {
388 let (rest, _parsed) = ParseContainer::from("test").split_at(1);
389 println!("rest = {rest}");
390 rest.split_at(3); rest.split_at(4);
392 }
393}