use crate::item::Node;
use crate::parser::combinators::alt::alt3;
use crate::parser::combinators::many::many0;
use crate::parser::combinators::tag::tag;
use crate::parser::combinators::take::{take_until, take_until_either_or};
use crate::parser::combinators::tuple::{tuple2, tuple3, tuple5};
use crate::parser::combinators::value::value;
use crate::parser::combinators::whitespace::whitespace0;
use crate::parser::xml::dtd::extsubset::extsubsetdecl;
use crate::parser::xml::dtd::pereference::petextreference;
use crate::parser::{ParseError, ParseInput, StaticState};
use qualname::{NamespacePrefix, NamespaceUri};
pub(crate) fn conditionalsect<'a, N: Node, L>()
-> impl Fn(ParseInput<'a, N>, &mut StaticState<L>) -> Result<(ParseInput<'a, N>, ()), ParseError>
where
L: FnMut(&NamespacePrefix) -> Result<NamespaceUri, ParseError>,
{
move |(input, state), ss| match tuple5(
tag("<!["),
whitespace0(),
alt3(
petextreference(),
value(tag("INCLUDE"), "INCLUDE".to_string()),
value(tag("IGNORE"), "IGNORE".to_string()),
),
whitespace0(),
tag("["),
)((input, state), ss)
{
Ok(((input2, state2), (_, _, ii, _, _))) => match ii.as_str() {
"INCLUDE" => includesect()((input2, state2), ss),
"IGNORE" => ignoresect()((input2, state2), ss),
_ => Err(ParseError::Combinator(String::from("conditionalsect"))),
},
Err(e) => Err(e),
}
}
pub(crate) fn includesect<'a, N: Node, L>()
-> impl Fn(ParseInput<'a, N>, &mut StaticState<L>) -> Result<(ParseInput<'a, N>, ()), ParseError>
where
L: FnMut(&NamespacePrefix) -> Result<NamespaceUri, ParseError>,
{
move |(input, state), ss| match tuple2(extsubsetdecl(), tag("]]>"))((input, state), ss) {
Ok(((input2, state2), (_, _))) => Ok(((input2, state2), ())),
Err(e) => Err(e),
}
}
pub(crate) fn ignoresect<'a, N: Node, L>()
-> impl Fn(ParseInput<'a, N>, &mut StaticState<L>) -> Result<(ParseInput<'a, N>, ()), ParseError>
where
L: FnMut(&NamespacePrefix) -> Result<NamespaceUri, ParseError>,
{
move |(input, state), ss| match tuple2(ignoresectcontents(), tag("]]>"))(
(input, state.clone()),
ss,
) {
Ok(((input2, _), (_, _))) => Ok(((input2, state), ())),
Err(e) => Err(e),
}
}
fn ignoresectcontents<'a, N: Node, L>()
-> impl Fn(ParseInput<'a, N>, &mut StaticState<L>) -> Result<(ParseInput<'a, N>, ()), ParseError>
where
L: FnMut(&NamespacePrefix) -> Result<NamespaceUri, ParseError>,
{
move |(input, state), ss| match tuple2(
many0(tuple2(
take_until_either_or("<![", "]]>"),
tuple3(tag("<!["), ignoresectcontents(), tag("]]>")),
)),
take_until("]]>"),
)((input, state.clone()), ss)
{
Ok(((input2, _), (_, _))) => Ok(((input2, state), ())),
Err(e) => Err(e),
}
}