use libdawg::dawg::builder::build_dawg;
use libdawg::dawg::{Arena, DawgNode};
struct Wordlist<'w> {
root: &'w DawgNode<'w, char>,
}
impl<'w> Wordlist<'w> {
fn new(root: &'w DawgNode<'w, char>) -> Self {
Wordlist { root }
}
fn is_word(&self, word: &str) -> bool {
word.chars()
.try_fold(self.root, |node, ch| node.get(ch))
.is_some_and(|n| n.is_word())
}
fn has_prefix(&self, prefix: &str) -> bool {
prefix
.chars()
.try_fold(self.root, |node, ch| node.get(ch))
.is_some()
}
fn all_words(&self) -> Vec<String> {
let mut words = Vec::new();
let mut stack = Vec::new();
Self::collect_words(self.root, &mut stack, &mut words);
words
}
fn collect_words(
node: &DawgNode<'_, char>,
prefix: &mut Vec<char>,
words: &mut Vec<String>,
) {
if node.is_word() {
words.push(prefix.iter().collect());
}
for (ch, child) in node.children() {
prefix.push(ch);
Self::collect_words(child, prefix, words);
prefix.pop();
}
}
}
fn main() {
let arena = Arena::new();
let words = ["BAKE", "BAKED", "BAKER", "CAKE", "CAKED", "FAKE", "LAKE"];
let root = build_dawg(&arena, words).unwrap();
let wordlist = Wordlist::new(root);
println!("Word lookup:");
for word in ["BAKE", "BAKER", "BAKES", "CAKE", "LAKE", "MAKE"] {
println!(" {word}: {}", if wordlist.is_word(word) { "yes" } else { "no" });
}
println!("\nPrefix checking:");
for prefix in ["BA", "CAK", "MA", "FAK"] {
println!(" {prefix}*: {}", if wordlist.has_prefix(prefix) { "yes" } else { "no" });
}
println!("\nAll words: {:?}", wordlist.all_words());
}