refactor(dictgen): Pull out custom str

This commit is contained in:
Ed Page 2024-12-30 10:56:06 -06:00
parent dbfc372120
commit db16cb53c5
4 changed files with 94 additions and 90 deletions

View file

@ -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<unicase::UniCase<&'s str>> 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<InsensitiveStr<'s2>> 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<H: core::hash::Hasher>(&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<H: core::hash::Hasher>(&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<InsensitiveStr<'b>> for InsensitiveStr<'a> {
fn borrow(&self) -> &InsensitiveStr<'b> {
self
}
}

View file

@ -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::*;

View file

@ -70,30 +70,3 @@ impl<V> DictMap<V> {
self.map.entries().map(|(k, v)| (k.convert(), v))
}
}
impl phf_shared::PhfHash for crate::InsensitiveStr<'_> {
#[inline]
fn phf_hash<H: core::hash::Hasher>(&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<crate::InsensitiveStr<'b>> for crate::InsensitiveStr<'a> {
fn borrow(&self) -> &crate::InsensitiveStr<'b> {
self
}
}

View file

@ -53,7 +53,7 @@ impl DictTableGen<'_> {
}
pub struct DictTable<V: 'static> {
pub keys: &'static [InsensitiveStr<'static>],
pub keys: &'static [crate::InsensitiveStr<'static>],
pub values: &'static [V],
pub range: core::ops::RangeInclusive<usize>,
}
@ -74,65 +74,3 @@ impl<V> DictTable<V> {
(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<unicase::UniCase<&'s str>> 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<InsensitiveStr<'s2>> 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<H: core::hash::Hasher>(&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)
}
}