serde_hkx/xml/de/parser/
mod.rs

1//! XML parser combinator
2pub mod tag;
3pub mod type_kind;
4
5use winnow::ascii::multispace0;
6use winnow::combinator::{alt, delimited, fail, repeat};
7use winnow::error::{ContextError, StrContext, StrContextValue};
8use winnow::token::take_until;
9use winnow::{ModalResult, Parser};
10
11/// Parses a string with surrounding whitespace(0 or more times)
12///
13/// # Note
14/// Has expected info.
15pub fn delimited_with_multispace0<'a>(
16    s: &'static str,
17) -> impl Parser<&'a str, &'a str, ContextError> {
18    delimited(multispace0, s, multispace0)
19        .context(StrContext::Expected(StrContextValue::StringLiteral(s)))
20}
21
22/// Analyze in the following order.
23/// - `Comments or multi spaces` -> `s` -> `multi spaces`
24///
25/// # Note
26/// Has expected info.
27pub fn delimited_comment_multispace0<'a>(
28    s: &'static str,
29) -> impl Parser<&'a str, &'a str, ContextError> {
30    delimited(comment_multispace0, s, multispace0)
31        .context(StrContext::Expected(StrContextValue::StringLiteral(s)))
32}
33
34/// Analyze in the following order.
35/// - `multi spaces` -> `s` -> `Comments or multi spaces`
36///
37/// # Note
38/// Has expected info.
39pub fn delimited_multispace0_comment<'a>(
40    s: &'static str,
41) -> impl Parser<&'a str, &'a str, ContextError> {
42    delimited(multispace0, s, comment_multispace0)
43        .context(StrContext::Expected(StrContextValue::StringLiteral(s)))
44}
45
46/// Skip comments and whitespace (0 or more times).
47///
48/// # Errors
49/// When parse failed.
50pub fn comment_multispace0(input: &mut &str) -> ModalResult<()> {
51    repeat(
52        0..,
53        alt((
54            ' ',
55            '\t',
56            '\r',
57            '\n',
58            comment.map(|_| ' '),
59            fail.context(StrContext::Expected(StrContextValue::CharLiteral(' ')))
60                .context(StrContext::Expected(StrContextValue::CharLiteral('\t')))
61                .context(StrContext::Expected(StrContextValue::CharLiteral('\r')))
62                .context(StrContext::Expected(StrContextValue::CharLiteral('\n')))
63                .context(StrContext::Expected(StrContextValue::Description(
64                    "Comment: (e.g. `<!-- comment -->`",
65                ))),
66        )),
67    )
68    .parse_next(input)
69}
70
71/// Skip comments and whitespace (1 or more times).
72///
73/// # Errors
74/// When parse failed.
75pub fn comment_multispace1(input: &mut &str) -> ModalResult<()> {
76    repeat(
77        1..,
78        alt((
79            ' ',
80            '\t',
81            '\r',
82            '\n',
83            comment.map(|_| ' '),
84            fail.context(StrContext::Expected(StrContextValue::CharLiteral(' ')))
85                .context(StrContext::Expected(StrContextValue::CharLiteral('\t')))
86                .context(StrContext::Expected(StrContextValue::CharLiteral('\r')))
87                .context(StrContext::Expected(StrContextValue::CharLiteral('\n')))
88                .context(StrContext::Expected(StrContextValue::Description(
89                    "Comment: (e.g. `<!-- comment -->`",
90                ))),
91        )),
92    )
93    .parse_next(input)
94}
95
96/// Parses a XML comment.
97/// - e.g. ` memSizeAndFlags SERIALIZE_IGNORED ` in `<!-- memSizeAndFlags SERIALIZE_IGNORED -->`
98///
99/// # Errors
100/// When parse failed.
101pub fn comment<'a>(input: &mut &'a str) -> ModalResult<&'a str> {
102    delimited("<!--", take_until(0.., "-->"), "-->")
103        .context(StrContext::Expected(StrContextValue::Description(
104            "comment",
105        )))
106        .parse_next(input)
107}