use std::{collections::HashMap, rc::Rc}; use itertools::Itertools; use crate::{candidate::{Candidate, CandidateName}, party::Party}; #[derive(Debug)] pub struct Header { pub parties: Vec, pub candidates: Vec, pub winners: usize, } impl Header { pub fn parse(row: quick_csv::Row, winners: usize) -> Result, Box> { 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 { self.candidates.iter().map(|v| v.get_name(self)) } }