pub mod interface;
pub mod macros;
pub mod methods;
pub mod metrics;
pub mod models;
pub mod utils;
pub use interface::WithVotes;
use methods::get_method_function;
pub use methods::Method;
pub use models::Candidacy;
use utils::clear_results;
pub struct SimpleElection {
pub results: Vec<Candidacy>,
pub seats: u16,
pub method: Method,
pub cutoff: f32,
}
impl SimpleElection {
pub fn new(results: Vec<Candidacy>, seats: u16, method: Method) -> Self {
SimpleElection {
results,
seats,
method,
cutoff: 0.0,
}
}
pub fn total_votes(&self) -> u32 {
self.results.iter().map(|c| c.get_votes()).sum()
}
pub fn compute(&mut self) -> Result<(), &str> {
let fun = get_method_function(self.method);
let total_votes = self.total_votes() as f32;
let cutoff_votes = (total_votes * self.cutoff) as u32;
clear_results(self.results.as_mut());
let mut filtered_results = self
.results
.iter_mut()
.filter(|c| c.get_votes() > cutoff_votes)
.map(|c| Box::new(c))
.collect::<Vec<_>>();
fun(&mut filtered_results, self.seats).unwrap();
Ok(())
}
}
#[cfg(test)]
mod tests {
use interface::WithSeats;
use super::*;
#[test]
fn test_simple_election() {
let mut election = election!(
vec![
candidacy!(2010, 9),
candidacy!(1018, 4),
candidacy!(86),
candidacy!(77),
],
13,
Method::DHONDT
);
election.compute().unwrap();
election.results.iter().for_each(|c| println!("{:?}", c));
}
#[test]
fn test_load_new_election() {
let _ = SimpleElection::new(
vec![
candidacy!(2010),
candidacy!(1018),
candidacy!(86),
candidacy!(77),
],
13,
Method::DHONDT,
);
}
#[test]
fn test_with_cutoff() {
let mut res = election!(
vec![candidacy!(10, 0), candidacy!(1, 0),],
13,
Method::DHONDT,
0.1
);
res.compute().unwrap();
assert_eq!(res.results.len(), 2);
assert_eq!(res.results[0].get_seats(), 13);
assert_eq!(res.results[1].get_seats(), 0);
}
}