/* OpenTally: Open-source election vote counting * Copyright © 2021–2022 Lee Yingtong Li (RunasSudo) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ use crate::election::Candidate; use nohash_hasher::BuildNoHashHasher; use std::{collections::{HashMap, hash_map}, ops::Index}; /// Newtype for [HashMap] on [Candidate]s #[derive(Clone)] pub struct CandidateMap<'e, V> { // TODO: Can we implement this more efficiently as a Vec? map: HashMap<&'e Candidate, V, BuildNoHashHasher> } impl<'e, V> CandidateMap<'e, V> { /// See [HashMap::new] pub fn new() -> Self { Self { map: HashMap::with_hasher(BuildNoHashHasher::default()) } } /// See [HashMap::with_capacity] pub fn with_capacity(capacity: usize) -> Self { Self { map: HashMap::with_capacity_and_hasher(capacity, BuildNoHashHasher::default()) } } /// See [HashMap::len] #[inline] pub fn len(&self) -> usize { return self.map.len(); } /// See [HashMap::insert] #[inline] pub fn insert(&mut self, candidate: &'e Candidate, value: V) { self.map.insert(candidate, value); } /// See [HashMap::get] #[inline] pub fn get(&self, candidate: &'e Candidate) -> Option<&V> { return self.map.get(candidate); } /// See [HashMap::get_mut] #[inline] pub fn get_mut(&mut self, candidate: &'e Candidate) -> Option<&mut V> { return self.map.get_mut(candidate); } /// See [HashMap::iter] #[inline] pub fn iter(&self) -> hash_map::Iter<&'e Candidate, V> { return self.map.iter(); } /// See [HashMap::iter_mut] #[inline] pub fn iter_mut(&mut self) -> hash_map::IterMut<&'e Candidate, V> { return self.map.iter_mut(); } /// See [HashMap::values] #[inline] pub fn values(&self) -> hash_map::Values<&'e Candidate, V> { return self.map.values(); } } impl<'e, V> Index<&Candidate> for CandidateMap<'e, V> { type Output = V; fn index(&self, candidate: &Candidate) -> &Self::Output { return &self.map[candidate]; } } impl<'e, V> IntoIterator for CandidateMap<'e, V> { type Item = (&'e Candidate, V); type IntoIter = hash_map::IntoIter<&'e Candidate, V>; fn into_iter(self) -> Self::IntoIter { return self.map.into_iter(); } }