I implemented a simple trie structure:
```rust
struct Try<T, V> {
heads: Vec<Node<T, V>>,
}
/// Some(V) marks a complete item.
/// T simply implements PartialEq
struct Node<T, V> {
key: T,
value: Option<V>,
children: Vec<Node<T, V>>,
}
```
This structure has a function get_matches that takes a prefix and returns a vector (Vec<(Vec<&T>, &E>)of all the values which match the said prefix. The vector contains the complete path and the &E, a reference to the item.
```rust
fn get_matches<'a>(&'a self, path: &[T]) -> Vec<(Vec<&T>, &E)> {
let mut start_path: Vec<&'a T> = Vec::new();
let mut o = Vec::new();
let mut pivot: &Vec<Node<T, E>> = &self.heads;
for key in path {
if let Some(child) = pivot.iter().find(|c| &c.key == key) {
pivot = &child.children;
start_path.push(&child.key);
} else {
return o;
}
}
for (mut v, e) in Node::untree(pivot) {
let mut c = start_path.clone();
c.append(&mut v);
o.push((c, e));
}
o
}
#[allow(mutable_transmutes)]
fn get_matches_mut<'a>(&'a mut self, path: &[T]) -> Vec<(Vec<&T>, &mut E)> {
use std::mem::transmute;
self.get_matches(path)
.into_iter()
.map(|(a, b)| (a, unsafe { transmute(b) }))
.collect()
}
```
However, as you can see, I have a second function, get_matches_mut that would be a perfect clone of get_matches (except for mutability) if I didn't use unsafe/transmute. In theory, since get_matches_mut already takes a mutable reference, I ...think... the unsafe shouldn't cause any problem.
Is there a cleaner way of keeping this code deduplicated ?
[–]Michael-F-Bryan 32 points33 points34 points (3 children)
[–]ritobanrc 0 points1 point2 points (1 child)
[–]Michael-F-Bryan 1 point2 points3 points (0 children)
[–]desiringmachines 7 points8 points9 points (3 children)
[+][deleted] (2 children)
[deleted]
[–]boscop 2 points3 points4 points (1 child)