bparse/pattern/byte.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
//! Patterns that only match against byte slices
use crate::pattern::Prefix;
use crate::{Choice, Pattern};
/// Returns a byte pattern that will match the utf8 string slice `s` at the start of the input.
///
/// ```
/// use bparse::{Pattern, byte::utf8};
///
/// let pattern = utf8("he");
/// assert_eq!(pattern.eval(b"hello"), Some(2));
/// ```
///
/// As a convenience, the `Pattern` trait is implemented for string slices with the same effect:
///
/// ```
/// use bparse::Pattern;
///
/// assert_eq!("he".eval(b"hello"), Some(2));
/// ```
pub fn utf8(s: &str) -> Prefix<u8> {
Prefix(s.as_bytes())
}
impl Pattern<u8> for &str {
fn eval(&self, input: &[u8]) -> Option<usize> {
utf8(self).eval(input)
}
}
/// Returns a pattern that will match any byte in `bytes` at the start of the input
///
/// ```
/// use bparse::{Pattern, byte::oneof};
///
/// let pattern = oneof(b"?!.:");
/// assert_eq!(pattern.eval(b"hi"), None);
/// assert_eq!(pattern.eval(b"!!"), Some(1));
/// assert_eq!(pattern.eval(b":"), Some(1));
/// ```
pub fn oneof(bytes: &[u8]) -> ByteLookupTable {
let mut set: [bool; 256] = [false; 256];
let mut i = 0;
while i < bytes.len() {
set[bytes[i] as usize] = true;
i += 1;
}
ByteLookupTable(set)
}
/// Inverse of [`oneof`].
pub fn noneof(bytes: &[u8]) -> ByteLookupTable {
let mut set = oneof(bytes).0;
let mut i = 0;
while i < set.len() {
set[i] = !set[i];
i += 1;
}
ByteLookupTable(set)
}
/// See [`oneof`]
#[derive(Debug, Clone, Copy)]
pub struct ByteLookupTable([bool; 256]);
impl Pattern<u8> for ByteLookupTable {
fn eval<'i>(&self, input: &[u8]) -> Option<usize> {
let first = *input.first()?;
if self.0[first as usize] {
return Some(1);
}
None
}
}
/// Returns a pattern that will match any ascii digit at the start of the input
///
/// ```
/// use bparse::{Pattern, byte::digit};
///
/// assert_eq!(digit().eval(b"a"), None);
/// assert_eq!(digit().eval(b"8"), Some(1));
/// ```
pub fn digit() -> ByteLookupTable {
oneof(b"0123456789")
}
/// Returns a pattern that will match any ascii letter at the start of the input
///
/// ```
/// use bparse::{Pattern, byte::alpha};
///
/// assert_eq!(alpha().eval(b"1"), None);
/// assert_eq!(alpha().eval(b"a"), Some(1));
/// ```
pub fn alpha() -> ByteLookupTable {
oneof(b"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
}
/// Returns a pattern that will match any hexadecimal character at the start of the input
///
/// ```
/// use bparse::{Pattern, byte::hex};
///
/// assert_eq!(hex().eval(b"z"), None);
/// assert_eq!(hex().eval(b"f"), Some(1));
/// ```
pub fn hex() -> Choice<ByteLookupTable, ByteLookupTable> {
oneof(b"abcdefABCDEF").or(digit())
}