pub(crate) const fn is_bchar(b: u8) -> bool {
b.is_ascii_alphanumeric()
|| matches!(
b,
b'\''
| b'('
| b')'
| b'+'
| b'_'
| b','
| b'-'
| b'.'
| b'/'
| b':'
| b'='
| b'?'
| b' '
)
}
pub(crate) const fn is_tchar(b: u8) -> bool {
b.is_ascii_alphanumeric()
|| matches!(
b,
b'!' | b'#'
| b'$'
| b'%'
| b'&'
| b'\''
| b'*'
| b'+'
| b'-'
| b'.'
| b'^'
| b'_'
| b'`'
| b'|'
| b'~'
)
}
pub(crate) const fn is_ows(b: u8) -> bool {
b == b' ' || b == b'\t'
}
pub(crate) fn is_valid_boundary(b: &[u8]) -> bool {
!b.is_empty() && b.len() <= 70 && b.iter().all(|&c| is_bchar(c)) && b.last() != Some(&b' ')
}
pub(crate) fn trim_ows(mut s: &[u8]) -> &[u8] {
while let Some((&first, rest)) = s.split_first() {
if is_ows(first) {
s = rest;
} else {
break;
}
}
while let Some((&last, rest)) = s.split_last() {
if is_ows(last) {
s = rest;
} else {
break;
}
}
s
}
pub(crate) fn eq_ignore_case(a: &[u8], b: &[u8]) -> bool {
a.len() == b.len() && a.iter().zip(b).all(|(x, y)| x.eq_ignore_ascii_case(y))
}
pub(crate) fn ows_trimmed_range(s: &[u8]) -> (usize, usize) {
let start = s.iter().take_while(|&&b| is_ows(b)).count();
let trailing = s.iter().rev().take_while(|&&b| is_ows(b)).count();
let end = s.len().saturating_sub(trailing).max(start);
(start, end)
}