mod get_parser;
mod non_parsing_methods;
mod parse_errors;
mod primitive_parsing;
pub use self::{
get_parser::{ParserFor, StdParser},
parse_errors::{ErrorKind, ParseDirection, ParseError, ParseValueResult, ParserResult},
};
#[cfg_attr(feature = "parsing", doc = "```rust")]
#[cfg_attr(not(feature = "parsing"), doc = "```ignore")]
#[cfg_attr(feature = "docsrs", doc(cfg(feature = "parsing_no_proc")))]
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
pub struct Parser<'a> {
parse_direction: ParseDirection,
start_offset: u32,
bytes: &'a [u8],
}
impl<'a> Parser<'a> {
#[inline]
pub const fn next_byte(mut self) -> ParseValueResult<'a, u8> {
try_parsing! {self, FromStart, ret;
if let [byte, rem @ ..] = self.bytes {
self.bytes = rem;
*byte
} else {
throw!(ErrorKind::SkipByte)
}
}
}
pub const fn skip(mut self, bytes: usize) -> Self {
parsing! {self, FromStart;
self.bytes = crate::slice::slice_from(self.bytes, bytes);
}
}
#[inline]
pub const fn strip_prefix(self, matched: &str) -> Result<Self, ParseError<'a>> {
self.strip_prefix_b(matched.as_bytes())
}
pub const fn strip_prefix_b(mut self, mut matched: &[u8]) -> Result<Self, ParseError<'a>> {
try_parsing! {self, FromStart;
impl_bytes_function!{
strip_prefix;
left = self.bytes;
right = matched;
on_error = throw!(ErrorKind::Strip),
}
}
}
pub const fn strip_prefix_u8(mut self, matched: u8) -> Result<Self, ParseError<'a>> {
try_parsing! {self, FromStart;
match self.bytes {
[byte, rem @ ..] if *byte == matched => {
self.bytes = rem;
}
_ => throw!(ErrorKind::Strip),
}
}
}
#[inline]
pub const fn strip_suffix(self, matched: &str) -> Result<Self, ParseError<'a>> {
self.strip_suffix_b(matched.as_bytes())
}
pub const fn strip_suffix_b(mut self, mut matched: &[u8]) -> Result<Self, ParseError<'a>> {
try_parsing! {self, FromEnd;
impl_bytes_function!{
strip_suffix;
left = self.bytes;
right = matched;
on_error = throw!(ErrorKind::Strip),
}
}
}
pub const fn strip_suffix_u8(mut self, matched: u8) -> Result<Self, ParseError<'a>> {
try_parsing! {self, FromEnd;
match self.bytes {
[rem @ .., byte] if *byte == matched => {
self.bytes = rem;
}
_ => throw!(ErrorKind::Strip),
}
}
}
pub const fn trim_start(mut self) -> Self {
parsing! {self, FromStart;
self.bytes = crate::slice::bytes_trim_start(self.bytes);
}
}
pub const fn trim_end(mut self) -> Self {
parsing! {self, FromEnd;
self.bytes = crate::slice::bytes_trim_end(self.bytes);
}
}
pub const fn trim_start_matches(self, needle: &str) -> Self {
self.trim_start_matches_b(needle.as_bytes())
}
pub const fn trim_start_matches_b(mut self, needle: &[u8]) -> Self {
parsing! {self, FromStart;
self.bytes = crate::slice::bytes_trim_start_matches(self.bytes, needle);
}
}
pub const fn trim_start_matches_u8(mut self, needle: u8) -> Self {
parsing! {self, FromStart;
while let [b, rem @ ..] = self.bytes {
if *b == needle {
self.bytes = rem;
} else {
break;
}
}
}
}
pub const fn trim_end_matches(self, needle: &str) -> Self {
self.trim_end_matches_b(needle.as_bytes())
}
pub const fn trim_end_matches_b(mut self, needle: &[u8]) -> Self {
parsing! {self, FromEnd;
self.bytes = crate::slice::bytes_trim_end_matches(self.bytes, needle);
}
}
pub const fn trim_end_matches_u8(mut self, needle: u8) -> Self {
parsing! {self, FromEnd;
while let [rem @ .., b] = self.bytes {
if *b == needle {
self.bytes = rem;
} else {
break;
}
}
}
}
pub const fn find_skip(self, needle: &str) -> Result<Self, ParseError<'a>> {
self.find_skip_b(needle.as_bytes())
}
pub const fn find_skip_b(mut self, needle: &[u8]) -> Result<Self, ParseError<'a>> {
try_parsing! {self, FromStart;
self.bytes = match crate::slice::bytes_find_skip(self.bytes, needle) {
Some(x) => x,
None => throw!(ErrorKind::Find),
};
}
}
pub const fn find_skip_u8(mut self, needle: u8) -> Result<Self, ParseError<'a>> {
try_parsing! {self, FromStart;
while let [byte, rem @ ..] = self.bytes {
self.bytes = rem;
if *byte == needle {
ret_!();
}
}
throw!(ErrorKind::Find)
}
}
pub const fn rfind_skip(self, needle: &str) -> Result<Self, ParseError<'a>> {
self.rfind_skip_b(needle.as_bytes())
}
pub const fn rfind_skip_b(mut self, needle: &[u8]) -> Result<Self, ParseError<'a>> {
try_parsing! {self, FromEnd;
self.bytes = match crate::slice::bytes_rfind_skip(self.bytes, needle) {
Some(x) => x,
None => throw!(ErrorKind::Find),
};
}
}
pub const fn rfind_skip_u8(mut self, needle: u8) -> Result<Self, ParseError<'a>> {
try_parsing! {self, FromEnd;
while let [rem @ .., byte] = self.bytes {
self.bytes = rem;
if *byte == needle {
ret_!();
}
}
throw!(ErrorKind::Find)
}
}
}