fix(dictgen)!: Allow case-sensitive ordered maps

This commit is contained in:
Ed Page 2024-12-30 15:39:34 -06:00
parent 086f9d1558
commit e7ff9cfc01
10 changed files with 650558 additions and 636484 deletions

File diff suppressed because it is too large Load diff

View file

@ -51,6 +51,18 @@ impl<'s2> PartialEq<InsensitiveStr<'s2>> for InsensitiveStr<'_> {
impl Eq for InsensitiveStr<'_> {} impl Eq for InsensitiveStr<'_> {}
impl PartialOrd for InsensitiveStr<'_> {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
Some(self.cmp(other))
}
}
impl Ord for InsensitiveStr<'_> {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
self.convert().cmp(&other.convert())
}
}
impl core::hash::Hash for InsensitiveStr<'_> { impl core::hash::Hash for InsensitiveStr<'_> {
#[inline] #[inline]
fn hash<H: core::hash::Hasher>(&self, hasher: &mut H) { fn hash<H: core::hash::Hasher>(&self, hasher: &mut H) {

View file

@ -14,6 +14,7 @@ impl OrderedMapGen<'_> {
data.sort_unstable_by_key(|v| unicase::UniCase::new(v.0)); data.sort_unstable_by_key(|v| unicase::UniCase::new(v.0));
let name = self.gen.name; let name = self.gen.name;
let key_type = "dictgen::InsensitiveStr<'static>";
let value_type = self.gen.value_type; let value_type = self.gen.value_type;
let mut smallest = usize::MAX; let mut smallest = usize::MAX;
@ -21,7 +22,7 @@ impl OrderedMapGen<'_> {
writeln!( writeln!(
file, file,
"pub static {name}: dictgen::OrderedMap<{value_type}> = dictgen::OrderedMap {{" "pub static {name}: dictgen::OrderedMap<{key_type}, {value_type}> = dictgen::OrderedMap {{"
)?; )?;
writeln!(file, " keys: &[")?; writeln!(file, " keys: &[")?;
for (key, _value) in data.iter() { for (key, _value) in data.iter() {
@ -52,13 +53,13 @@ impl OrderedMapGen<'_> {
} }
} }
pub struct OrderedMap<V: 'static> { pub struct OrderedMap<K: 'static, V: 'static> {
pub keys: &'static [crate::InsensitiveStr<'static>], pub keys: &'static [K],
pub values: &'static [V], pub values: &'static [V],
pub range: core::ops::RangeInclusive<usize>, pub range: core::ops::RangeInclusive<usize>,
} }
impl<V> OrderedMap<V> { impl<V> OrderedMap<crate::InsensitiveStr<'_>, V> {
#[inline] #[inline]
pub fn find(&self, word: &'_ unicase::UniCase<&str>) -> Option<&'static V> { pub fn find(&self, word: &'_ unicase::UniCase<&str>) -> Option<&'static V> {
if self.range.contains(&word.len()) { if self.range.contains(&word.len()) {
@ -71,3 +72,14 @@ impl<V> OrderedMap<V> {
} }
} }
} }
impl<V> OrderedMap<&str, V> {
#[inline]
pub fn find(&self, word: &'_ &str) -> Option<&'static V> {
if self.range.contains(&word.len()) {
self.keys.binary_search(word).map(|i| &self.values[i]).ok()
} else {
None
}
}
}

View file

@ -27,7 +27,7 @@ impl TrieGen<'_> {
pub struct Trie<V: 'static> { pub struct Trie<V: 'static> {
pub root: &'static TrieNode<V>, pub root: &'static TrieNode<V>,
pub unicode: &'static crate::OrderedMap<V>, pub unicode: &'static crate::OrderedMap<crate::InsensitiveStr<'static>, V>,
pub range: core::ops::RangeInclusive<usize>, pub range: core::ops::RangeInclusive<usize>,
} }
@ -91,7 +91,7 @@ pub struct TrieNode<V: 'static> {
pub enum TrieChild<V: 'static> { pub enum TrieChild<V: 'static> {
Nested(&'static [Option<&'static TrieNode<V>>; 26]), Nested(&'static [Option<&'static TrieNode<V>>; 26]),
Flat(&'static crate::OrderedMap<V>), Flat(&'static crate::OrderedMap<crate::InsensitiveStr<'static>, V>),
} }
#[cfg(feature = "codegen")] #[cfg(feature = "codegen")]

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff