use crate::errors::SyntaxError;
use crate::parser::Parser;
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
pub struct PiParser(
pub bool,
);
impl Parser for PiParser {
#[inline]
fn feed(&mut self, bytes: &[u8]) -> Option<usize> {
for i in memchr::memchr_iter(b'>', bytes) {
match i {
0 if self.0 => return Some(0),
i if i > 0 && bytes[i - 1] == b'?' => return Some(i),
_ => {}
}
}
self.0 = bytes.last().copied() == Some(b'?');
None
}
#[inline]
fn eof_error() -> SyntaxError {
SyntaxError::UnclosedPIOrXmlDecl
}
}
#[test]
fn pi() {
use pretty_assertions::assert_eq;
fn parse_pi(bytes: &[u8], had_question_mark: bool) -> Result<usize, bool> {
let mut parser = PiParser(had_question_mark);
match parser.feed(bytes) {
Some(i) => Ok(i),
None => Err(parser.0),
}
}
assert_eq!(parse_pi(b"", false), Err(false)); assert_eq!(parse_pi(b"", true), Err(false));
assert_eq!(parse_pi(b"?", false), Err(true)); assert_eq!(parse_pi(b"?", true), Err(true));
assert_eq!(parse_pi(b">", false), Err(false)); assert_eq!(parse_pi(b">", true), Ok(0));
assert_eq!(parse_pi(b"?>", false), Ok(1)); assert_eq!(parse_pi(b"?>", true), Ok(1));
assert_eq!(parse_pi(b">?>", false), Ok(2)); assert_eq!(parse_pi(b">?>", true), Ok(0)); }