use radix_trie::{Trie, TrieCommon, TrieKey}; use super::FullyQualifiedSymbolName; use std::hash::{Hasher, Hash}; use std::collections::hash_map::DefaultHasher; #[derive(Debug)] pub struct SymbolTrie(Trie); impl TrieKey for FullyQualifiedSymbolName { fn encode_bytes(&self) -> Vec { let mut hasher = DefaultHasher::new(); let mut output = vec![]; let FullyQualifiedSymbolName(scopes) = self; for segment in scopes.iter() { segment.name.as_bytes().hash(&mut hasher); output.extend_from_slice(&hasher.finish().to_be_bytes()); } output } } impl SymbolTrie { pub fn new() -> SymbolTrie { SymbolTrie(Trie::new()) } pub fn insert(&mut self, fqsn: &FullyQualifiedSymbolName) { self.0.insert(fqsn.clone(), ()); } pub fn get_children(&self, fqsn: &FullyQualifiedSymbolName) -> Vec { let subtrie = match self.0.subtrie(fqsn) { Some(s) => s, None => return vec![] }; let output: Vec = subtrie.keys().filter(|cur_key| **cur_key != *fqsn).map(|fqsn| fqsn.clone()).collect(); output } } #[test] fn test_trie_insertion() { let mut trie = SymbolTrie::new(); trie.insert(&fqsn!("unrelated"; ty, "thing"; tr)); trie.insert(&fqsn!("outer"; ty, "inner"; tr)); trie.insert(&fqsn!("outer"; ty, "inner"; ty, "still_inner"; tr)); let children = trie.get_children(&fqsn!("outer"; ty, "inner"; tr)); assert_eq!(children.len(), 1); }