use std::collections::{HashMap, HashSet};
use std::hash::{BuildHasherDefault, Hasher};
#[derive(Default)]
pub(crate) struct FxHasher(u64);
impl Hasher for FxHasher {
fn write(&mut self, bytes: &[u8]) {
const SEED: u64 = 0x51_7c_c1_b7_27_22_0a_95;
for &b in bytes {
self.0 = (self.0.rotate_left(5) ^ u64::from(b)).wrapping_mul(SEED);
}
}
fn finish(&self) -> u64 {
self.0
}
}
pub(crate) type FxMap<K, V> = HashMap<K, V, BuildHasherDefault<FxHasher>>;
pub(crate) type FxSet<K> = HashSet<K, BuildHasherDefault<FxHasher>>;
pub(crate) fn from_ordinal_number(input: &str) -> Option<&'static str> {
Some(match input {
"1st" | "First" => "1",
"2nd" | "Second" => "2",
"3rd" | "Third" => "3",
"4th" | "Fourth" => "4",
"5th" | "Fifth" => "5",
"6th" | "Sixth" => "6",
"7th" | "Seventh" => "7",
"8th" | "Eighth" => "8",
"9th" | "Ninth" => "9",
_ => return None,
})
}
pub(crate) fn from_roman_number(input: &str) -> Option<&'static str> {
Some(match input {
"II" => "2",
"III" => "3",
"IV" => "4",
_ => return None,
})
}
pub(crate) fn to_int(str: &str) -> i32 {
str.parse().unwrap_or(0)
}
pub(crate) fn equal_ignore_ascii_case(a: &str, b: &str) -> bool {
a.eq_ignore_ascii_case(b)
}
pub(crate) fn byte_to_char_offset(s: &str, byte_offset: usize) -> usize {
s.get(..byte_offset)
.map_or_else(|| s.chars().count(), |prefix| prefix.chars().count())
}