ballot-counter/src/header.rs

50 lines
1.4 KiB
Rust

use std::collections::HashMap;
use itertools::Itertools;
use crate::{candidate::{Candidate, CandidateName}, csv, party::Party};
#[derive(Debug)]
pub struct Header {
pub parties: Vec<Party>,
pub candidates: Vec<Candidate>,
pub winners: usize,
}
impl Header {
pub fn parse(row: csv::reader::RowReader, winners: usize) -> Result<Header, Box<dyn std::error::Error>> {
let mut parties = Vec::<Party>::new();
let mut candidates = Vec::<Candidate>::new();
let mut parties_lookup = HashMap::<&str, usize>::new();
for col in row.skip(6).collect_vec().iter() {
let [party, name] = col.split(':').next_array().ok_or("Missing ':'")?;
if party == "UG" { // independents
candidates.push(Candidate {
name: name.to_owned(),
party_id: None,
});
}
else if let Some(party_id) = parties_lookup.get(party).copied() {
parties[party_id].member_ids.push(candidates.len());
candidates.push(Candidate {
name: name.to_owned(),
party_id: Some(party_id),
});
}
else {
parties_lookup.insert(party, parties.len());
parties.push(Party::new(name.to_owned()));
}
}
return Ok(Header { parties, candidates, winners });
}
pub fn get_candidate_name(&self, index: usize) -> CandidateName {
self.candidates[index].get_name(self)
}
pub fn iter_candidate_name(&self) -> impl Iterator<Item = CandidateName> {
self.candidates.iter().map(|v| v.get_name(self))
}
}