use std::ops::RangeInclusive;
#[derive(Debug, PartialEq, Eq)]
enum FindRangeResult<'a> {
WasOnRangeStart,
Range(&'a RangeInclusive<u32>),
}
fn find_range_for_char(code: u32, ranges: &'_ [RangeInclusive<u32>]) -> FindRangeResult<'_> {
let index = ranges.binary_search_by_key(&code, |range| *range.start());
match index {
Ok(_) => FindRangeResult::WasOnRangeStart,
Err(index) => match index {
#[allow(clippy::arithmetic_side_effects, clippy::indexing_slicing)]
0 => FindRangeResult::Range(&ranges[0]),
#[allow(clippy::arithmetic_side_effects, clippy::indexing_slicing)]
index => FindRangeResult::Range(&ranges[index - 1]),
},
}
}
pub fn is_in_one_of_ranges(c: u32, ranges: &[RangeInclusive<u32>]) -> bool {
match find_range_for_char(c, ranges) {
FindRangeResult::WasOnRangeStart => true,
FindRangeResult::Range(range) => range.contains(&c),
}
}
#[inline(always)]
pub(crate) fn is_alpha(c: char) -> bool {
c.is_alphabetic()
}
#[inline(always)]
pub(crate) fn is_hex_digit(c: char) -> bool {
c.is_ascii_hexdigit()
}
#[inline(always)]
pub(crate) fn is_digit(c: char) -> bool {
c.is_ascii_digit()
}
pub(crate) fn is_sub_delim(c: char) -> bool {
matches!(
c,
'!' | '$' | '&' | '\'' | '(' | ')' | '*' | '+' | ',' | ';' | '='
)
}
pub(crate) fn is_unreserved(c: char) -> bool {
is_alpha(c) || is_digit(c) || is_ireg_special_chars(c)
}
pub(crate) fn is_ireg_special_chars(c: char) -> bool {
matches!(c, '_' | '.' | '-' | '~')
}
pub(crate) fn is_white_space(c: char) -> bool {
matches!(c, '\n' | '\r' | '\t' | ' ')
}
pub(crate) fn is_not_white_space(c: char) -> bool {
!is_white_space(c)
}
pub(crate) fn is_white_space_but_not_linebreak(c: char) -> bool {
matches!(c, '\t' | ' ')
}