56 lines
1.4 KiB
Rust
56 lines
1.4 KiB
Rust
use std::{collections::HashMap, rc::Rc};
|
|
|
|
use itertools::Itertools;
|
|
|
|
use crate::{candidate::{Candidate, CandidateName}, party::Party};
|
|
|
|
|
|
#[derive(Debug)]
|
|
pub struct Header {
|
|
pub parties: Vec<Party>,
|
|
pub candidates: Vec<Candidate>,
|
|
pub winners: usize,
|
|
}
|
|
|
|
impl Header {
|
|
pub fn parse(row: quick_csv::Row, winners: usize) -> Result<Rc<Header>, Box<dyn std::error::Error>> {
|
|
let mut header = Header {
|
|
parties: Vec::new(),
|
|
candidates: Vec::new(),
|
|
winners,
|
|
};
|
|
let mut parties_lookup = HashMap::<&str, usize>::new();
|
|
|
|
for col in row.columns()?.skip(6) {
|
|
let [party, name] = col.split(':').next_array().ok_or("Missing ':'")?;
|
|
|
|
if party == "UG" { // independents
|
|
header.candidates.push(Candidate {
|
|
name: name.to_owned(),
|
|
party_id: None,
|
|
});
|
|
}
|
|
else if let Some(party_id) = parties_lookup.get(party).copied() {
|
|
header.parties[party_id].member_ids.push(header.candidates.len());
|
|
header.candidates.push(Candidate {
|
|
name: name.to_owned(),
|
|
party_id: Some(party_id),
|
|
});
|
|
}
|
|
else {
|
|
parties_lookup.insert(party, header.parties.len());
|
|
header.parties.push(Party::new(name.to_owned()));
|
|
}
|
|
}
|
|
|
|
Ok(header.into())
|
|
}
|
|
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))
|
|
}
|
|
}
|
|
|