From da0e53679639f83406c663a46c91d7c5053f720a Mon Sep 17 00:00:00 2001 From: Ed Page Date: Mon, 30 Dec 2024 20:55:12 -0600 Subject: [PATCH] feat(dictgen): Generate a naive match After 23 minutes of compiling, I gave up. The compiler might generate fast `match`s but its not worth the compile time. --- crates/dictgen/src/gen.rs | 4 ++++ crates/dictgen/src/lib.rs | 4 ++++ crates/dictgen/src/match.rs | 37 +++++++++++++++++++++++++++++++++++++ 3 files changed, 45 insertions(+) create mode 100644 crates/dictgen/src/match.rs diff --git a/crates/dictgen/src/gen.rs b/crates/dictgen/src/gen.rs index 76b447a..256cc02 100644 --- a/crates/dictgen/src/gen.rs +++ b/crates/dictgen/src/gen.rs @@ -57,6 +57,10 @@ impl<'g> DictGen<'g> { limit: 64, } } + + pub fn r#match(self) -> crate::MatchGen<'g> { + crate::MatchGen { gen: self } + } } impl Default for DictGen<'static> { diff --git a/crates/dictgen/src/lib.rs b/crates/dictgen/src/lib.rs index fd1e330..345f0e7 100644 --- a/crates/dictgen/src/lib.rs +++ b/crates/dictgen/src/lib.rs @@ -7,6 +7,8 @@ mod gen; mod insensitive; #[cfg(feature = "map")] mod map; +#[cfg(feature = "codegen")] +mod r#match; mod ordered_map; mod trie; @@ -16,4 +18,6 @@ pub use insensitive::*; #[cfg(feature = "map")] pub use map::*; pub use ordered_map::*; +#[cfg(feature = "codegen")] +pub use r#match::*; pub use trie::*; diff --git a/crates/dictgen/src/match.rs b/crates/dictgen/src/match.rs new file mode 100644 index 0000000..7e510f6 --- /dev/null +++ b/crates/dictgen/src/match.rs @@ -0,0 +1,37 @@ +#[cfg(feature = "codegen")] +pub struct MatchGen<'g> { + pub(crate) gen: crate::DictGen<'g>, +} + +#[cfg(feature = "codegen")] +impl MatchGen<'_> { + pub fn write( + &self, + file: &mut W, + data: impl Iterator, V)>, + ) -> Result<(), std::io::Error> { + let mut data: Vec<_> = data.collect(); + data.sort_unstable_by_key(|v| unicase::UniCase::new(v.0.as_ref().to_owned())); + + let name = self.gen.name; + let value_type = self.gen.value_type; + + writeln!(file, "pub struct {name};")?; + writeln!(file, "impl {name} {{")?; + writeln!( + file, + " pub fn find(&self, word: &&str) -> Option<&'static {value_type}> {{" + )?; + writeln!(file, " match *word {{")?; + for (key, value) in data.iter() { + let key = key.as_ref(); + writeln!(file, " {key:?} => Some(&{value}.as_slice()),")?; + } + writeln!(file, " _ => None,")?; + writeln!(file, " }}")?; + writeln!(file, " }}")?; + writeln!(file, "}}")?; + + Ok(()) + } +}