1use crate::{
3 parse::Parse, processing_instruction::ProcessingInstruction, Document, Error, IResult,
4};
5use nom::{branch::alt, combinator::map};
6
7#[derive(Clone, PartialEq, Eq)]
8pub enum MiscState {
9 BeforeDoctype,
10 AfterDoctype,
11}
12
13#[derive(Clone, PartialEq, Eq)]
14pub struct Misc {
15 pub content: Box<Document>, pub state: MiscState,
17}
18
19impl<'a> Parse<'a> for Misc {
20 type Args = MiscState;
21 type Output = IResult<&'a str, Self>;
22
23 fn parse(input: &'a str, args: Self::Args) -> Self::Output {
25 let mut input_remaining = input;
26 let mut content_vec: Vec<Document> = vec![];
27 loop {
28 let parse_result = alt((
29 Document::parse_comment,
30 map(
31 |i| ProcessingInstruction::parse(i, ()),
32 Document::ProcessingInstruction,
33 ),
34 map(Self::parse_multispace1, |_| Document::Empty),
35 ))(input_remaining);
36
37 match parse_result {
38 Ok((remaining, document)) => {
39 match document {
40 Document::Empty => {} _ => content_vec.push(document),
42 }
43 input_remaining = remaining;
44 }
45
46 Err(_) => {
47 if !content_vec.is_empty() {
48 break;
49 } else {
50 return Err(nom::Err::Error(Error::NomError(nom::error::Error::new(
51 input.to_string(),
52 nom::error::ErrorKind::Many0,
53 ))));
54 }
55 }
56 }
57 }
58
59 let content = Box::new(Document::Nested(content_vec));
60 Ok((
61 input_remaining,
62 Misc {
63 content,
64 state: args,
65 },
66 ))
67 }
68}