106 lines
2.7 KiB
Rust
106 lines
2.7 KiB
Rust
|
/* 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 <https://www.gnu.org/licenses/>.
|
||
|
*/
|
||
|
|
||
|
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<Candidate>>
|
||
|
}
|
||
|
|
||
|
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();
|
||
|
}
|
||
|
}
|