diff --git a/crates/dictgen/src/insensitive.rs b/crates/dictgen/src/insensitive.rs new file mode 100644 index 0000000..0f7de86 --- /dev/null +++ b/crates/dictgen/src/insensitive.rs @@ -0,0 +1,91 @@ +/// `UniCase` look-alike that avoids const-fn so large tables don't OOM +#[derive(Copy, Clone)] +pub enum InsensitiveStr<'s> { + Unicode(&'s str), + Ascii(&'s str), +} + +impl<'s> InsensitiveStr<'s> { + pub fn convert(self) -> unicase::UniCase<&'s str> { + match self { + InsensitiveStr::Unicode(s) => unicase::UniCase::unicode(s), + InsensitiveStr::Ascii(s) => unicase::UniCase::ascii(s), + } + } + + pub fn into_inner(self) -> &'s str { + match self { + InsensitiveStr::Unicode(s) | InsensitiveStr::Ascii(s) => s, + } + } +} + +impl<'s> From> for InsensitiveStr<'s> { + fn from(other: unicase::UniCase<&'s str>) -> Self { + if other.is_ascii() { + InsensitiveStr::Ascii(other.into_inner()) + } else { + InsensitiveStr::Unicode(other.into_inner()) + } + } +} + +impl<'s2> PartialEq> for InsensitiveStr<'_> { + #[inline] + fn eq(&self, other: &InsensitiveStr<'s2>) -> bool { + self.convert() == other.convert() + } +} + +impl Eq for InsensitiveStr<'_> {} + +impl core::hash::Hash for InsensitiveStr<'_> { + #[inline] + fn hash(&self, hasher: &mut H) { + self.convert().hash(hasher); + } +} + +impl core::fmt::Debug for InsensitiveStr<'_> { + #[inline] + fn fmt(&self, fmt: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + core::fmt::Debug::fmt(self.into_inner(), fmt) + } +} + +impl core::fmt::Display for InsensitiveStr<'_> { + #[inline] + fn fmt(&self, fmt: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + core::fmt::Display::fmt(self.into_inner(), fmt) + } +} + +#[cfg(feature = "map")] +impl phf_shared::PhfHash for InsensitiveStr<'_> { + #[inline] + fn phf_hash(&self, state: &mut H) { + core::hash::Hash::hash(self, state); + } +} + +#[cfg(feature = "map")] +impl phf_shared::FmtConst for InsensitiveStr<'_> { + fn fmt_const(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + InsensitiveStr::Ascii(_) => f.write_str("dictgen::InsensitiveStr::Ascii(")?, + InsensitiveStr::Unicode(_) => { + f.write_str("dictgen::InsensitiveStr::Unicode(")?; + } + } + + self.into_inner().fmt_const(f)?; + f.write_str(")") + } +} + +#[cfg(feature = "map")] +impl<'b, 'a: 'b> phf_shared::PhfBorrow> for InsensitiveStr<'a> { + fn borrow(&self) -> &InsensitiveStr<'b> { + self + } +} diff --git a/crates/dictgen/src/lib.rs b/crates/dictgen/src/lib.rs index 988fac5..5b2fb82 100644 --- a/crates/dictgen/src/lib.rs +++ b/crates/dictgen/src/lib.rs @@ -4,6 +4,7 @@ #[cfg(feature = "codegen")] mod gen; +mod insensitive; #[cfg(feature = "map")] mod map; mod table; @@ -11,6 +12,7 @@ mod trie; #[cfg(feature = "codegen")] pub use gen::*; +pub use insensitive::*; #[cfg(feature = "map")] pub use map::*; pub use table::*; diff --git a/crates/dictgen/src/map.rs b/crates/dictgen/src/map.rs index ea7c106..f6a3260 100644 --- a/crates/dictgen/src/map.rs +++ b/crates/dictgen/src/map.rs @@ -70,30 +70,3 @@ impl DictMap { self.map.entries().map(|(k, v)| (k.convert(), v)) } } - -impl phf_shared::PhfHash for crate::InsensitiveStr<'_> { - #[inline] - fn phf_hash(&self, state: &mut H) { - core::hash::Hash::hash(self, state); - } -} - -impl phf_shared::FmtConst for crate::InsensitiveStr<'_> { - fn fmt_const(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - match self { - crate::InsensitiveStr::Ascii(_) => f.write_str("dictgen::InsensitiveStr::Ascii(")?, - crate::InsensitiveStr::Unicode(_) => { - f.write_str("dictgen::InsensitiveStr::Unicode(")?; - } - } - - self.into_inner().fmt_const(f)?; - f.write_str(")") - } -} - -impl<'b, 'a: 'b> phf_shared::PhfBorrow> for crate::InsensitiveStr<'a> { - fn borrow(&self) -> &crate::InsensitiveStr<'b> { - self - } -} diff --git a/crates/dictgen/src/table.rs b/crates/dictgen/src/table.rs index 56c688f..539f6ac 100644 --- a/crates/dictgen/src/table.rs +++ b/crates/dictgen/src/table.rs @@ -53,7 +53,7 @@ impl DictTableGen<'_> { } pub struct DictTable { - pub keys: &'static [InsensitiveStr<'static>], + pub keys: &'static [crate::InsensitiveStr<'static>], pub values: &'static [V], pub range: core::ops::RangeInclusive, } @@ -74,65 +74,3 @@ impl DictTable { (0..self.keys.len()).map(move |i| (self.keys[i].convert(), &self.values[i])) } } - -/// `UniCase` look-alike that avoids const-fn so large tables don't OOM -#[derive(Copy, Clone)] -pub enum InsensitiveStr<'s> { - Unicode(&'s str), - Ascii(&'s str), -} - -impl<'s> InsensitiveStr<'s> { - pub fn convert(self) -> unicase::UniCase<&'s str> { - match self { - InsensitiveStr::Unicode(s) => unicase::UniCase::unicode(s), - InsensitiveStr::Ascii(s) => unicase::UniCase::ascii(s), - } - } - - pub fn into_inner(self) -> &'s str { - match self { - InsensitiveStr::Unicode(s) | InsensitiveStr::Ascii(s) => s, - } - } -} - -impl<'s> From> for InsensitiveStr<'s> { - fn from(other: unicase::UniCase<&'s str>) -> Self { - if other.is_ascii() { - InsensitiveStr::Ascii(other.into_inner()) - } else { - InsensitiveStr::Unicode(other.into_inner()) - } - } -} - -impl<'s2> PartialEq> for InsensitiveStr<'_> { - #[inline] - fn eq(&self, other: &InsensitiveStr<'s2>) -> bool { - self.convert() == other.convert() - } -} - -impl Eq for InsensitiveStr<'_> {} - -impl core::hash::Hash for InsensitiveStr<'_> { - #[inline] - fn hash(&self, hasher: &mut H) { - self.convert().hash(hasher); - } -} - -impl core::fmt::Debug for InsensitiveStr<'_> { - #[inline] - fn fmt(&self, fmt: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - core::fmt::Debug::fmt(self.into_inner(), fmt) - } -} - -impl core::fmt::Display for InsensitiveStr<'_> { - #[inline] - fn fmt(&self, fmt: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - core::fmt::Display::fmt(self.into_inner(), fmt) - } -}