From e61f3ee1c433ecdab6a4c7cc0c36739f07ae8b96 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Tue, 6 Feb 2024 12:04:01 -0600 Subject: [PATCH] feat(token): Allow a byte to pass to tag --- src/stream/mod.rs | 43 +++++++++++++++++++++++++++++++++++++++++++ src/token/tests.rs | 15 +++++++++++++++ 2 files changed, 58 insertions(+) diff --git a/src/stream/mod.rs b/src/stream/mod.rs index 2051f9fe..31e6951f 100644 --- a/src/stream/mod.rs +++ b/src/stream/mod.rs @@ -454,6 +454,13 @@ impl<'a> SliceLen for &'a str { } } +impl SliceLen for u8 { + #[inline] + fn slice_len(&self) -> usize { + 1 + } +} + impl SliceLen for char { #[inline(always)] fn slice_len(&self) -> usize { @@ -2137,6 +2144,28 @@ impl<'a, 'b> Compare> for &'a [u8] { } } +impl<'a> Compare for &'a [u8] { + #[inline] + fn compare(&self, t: u8) -> CompareResult { + match self.first().copied() { + Some(c) if t == c => CompareResult::Ok(t.slice_len()), + Some(_) => CompareResult::Error, + None => CompareResult::Incomplete, + } + } +} + +impl<'a> Compare> for &'a [u8] { + #[inline] + fn compare(&self, t: AsciiCaseless) -> CompareResult { + match self.first() { + Some(c) if t.0.eq_ignore_ascii_case(c) => CompareResult::Ok(t.slice_len()), + Some(_) => CompareResult::Error, + None => CompareResult::Incomplete, + } + } +} + impl<'a> Compare for &'a [u8] { #[inline(always)] fn compare(&self, t: char) -> CompareResult { @@ -2165,6 +2194,20 @@ impl<'a, 'b> Compare> for &'a str { } } +impl<'a> Compare for &'a str { + #[inline(always)] + fn compare(&self, t: u8) -> CompareResult { + self.as_bytes().compare(t) + } +} + +impl<'a> Compare> for &'a str { + #[inline(always)] + fn compare(&self, t: AsciiCaseless) -> CompareResult { + self.as_bytes().compare(t) + } +} + impl<'a> Compare for &'a str { #[inline(always)] fn compare(&self, t: char) -> CompareResult { diff --git a/src/token/tests.rs b/src/token/tests.rs index dd334ac6..42003a34 100644 --- a/src/token/tests.rs +++ b/src/token/tests.rs @@ -204,6 +204,21 @@ fn complete_tag_char() { ); } +#[test] +fn complete_tag_byte() { + fn test(i: &[u8]) -> IResult<&[u8], &[u8]> { + tag(b'B').parse_peek(i) + } + assert_eq!(test(&[0x42, 0x00][..]), Ok((&b"\x00"[..], &b"\x42"[..]))); + assert_eq!( + test(&[b'A', b'\0'][..]), + Err(ErrMode::Backtrack(error_position!( + &&b"A\0"[..], + ErrorKind::Tag + ))) + ); +} + #[test] fn partial_any_str() { use super::any;