use super::*;
#[derive(Copy, Clone, Debug)]
pub struct ZeroBytePattern {
insensitive: bool,
marks: &'static [(&'static str, u32)],
message: &'static str,
}
impl<'i> FnOnce<(ParseState<'i>,)> for ZeroBytePattern {
type Output = ParseResult<'i, (u32, &'i str)>;
#[inline]
extern "rust-call" fn call_once(self, (input,): (ParseState<'i>,)) -> Self::Output {
for (mark, base) in self.marks {
match Self::parse_byte_base(input, *mark, *base, self.insensitive) {
Pending(s, v) => return s.finish(v),
_ => continue,
}
}
StopBecause::missing_character_set(self.message, input.start_offset)?
}
}
impl ZeroBytePattern {
pub const fn new(marks: &'static [(&'static str, u32)]) -> Self {
Self { insensitive: false, marks, message: "ZeroBytePattern" }
}
pub const fn with_insensitive(self, insensitive: bool) -> Self {
Self { insensitive, ..self }
}
pub const fn with_message(self, message: &'static str) -> Self {
Self { message, ..self }
}
pub fn parse_byte_base<'i>(
state: ParseState<'i>,
mark: &'static str,
base: u32,
insensitive: bool,
) -> ParseResult<'i, (u32, &'i str)> {
let (state, _) = match insensitive {
true => state.match_str_insensitive(mark)?,
false => state.match_str(mark)?,
};
let mut offset = 0;
for c in state.residual.chars() {
match c {
c if c.is_digit(base) => offset += 1,
_ => break,
}
}
let str = unsafe { state.residual.get_unchecked(..offset) };
state.advance(offset).finish((base, str))
}
}