struct HashMap<'a, K: PartialEq, V> { table: Vec>>, hash_fn: fn(&K) -> usize, } impl<'a, K: PartialEq, V> HashMap<'a, K, V> { fn new(hash_fn: fn(&K) -> usize) -> Self { HashMap { table: vec![None; 16], hash_fn, } } fn with_capacity(capacity: usize, hash_fn: fn(&K) -> usize) -> Self { HashMap { table: vec![None; capacity], hash_fn } } fn put(&mut self, k: &'a K, v: &'a V) { let hash = (self.hash_fn)(&k); let target_index = hash % self.table.capacity(); match self.table[target_index].take() { None => { let new_container = vec![(k, v)]; self.table.insert(target_index, Some(new_container)); }, Some(mut container) => { container.push((k, v)); self.table.insert(target_index, Some(container)); } } } fn get(&mut self, k: &K) -> Option<&V> { let hash = (self.hash_fn)(&k); let target_index = hash % self.table.capacity(); let container_opt = self.table[target_index].take(); if container_opt.is_none() { None } else { let container = container_opt.unwrap(); for item in container.iter() { if item.0 == k { let result = Some(item.1); self.table[target_index] = Some(container); return result; } } self.table[target_index] = Some(container); None } } } #[cfg(test)] mod hash_map_tests { use super::*; #[test] fn simple_put_and_get() { let jesse = String::from("Jesse"); let brault = String::from("Brault"); let mut map: HashMap = HashMap::new(|s| s.len()); map.put(&jesse, &brault); assert_eq!(map.get(&jesse), Some(&brault)); } #[test] fn put_and_get_with_str() { let jesse = "Jesse"; let brault = "Brault"; let mut map: HashMap<&str, &str> = HashMap::new(|s| s.len()); map.put(&jesse, &brault); assert_eq!(map.get(&jesse), Some(&brault)); } } fn main() { println!("Hello, world!"); }