fn read_from_senate_first_prefs_by_state_by_vote_typ_download_file2016(builder: &mut CandidateAndGroupInformationBuilder,path:&Path,state:&str) -> anyhow::Result<()> {
    let mut rdr = csv::Reader::from_reader(skip_first_line_of_file(path)?);
    for result in rdr.records() {
        let record = result?;
        if state==&record[0] { // right state
            let group_id = &record[1]; // something like A, B, or UG
            let candidate_id = &record[2]; // something like 32847
            if candidate_id!="0" {
                let position_in_ticket = record[3].parse::<usize>()?; // 0, 1, .. 0 means a dummy id for the group ticket.
                if builder.parties.len()==0 || &builder.parties[builder.parties.len()-1].group_id != group_id {
                    builder.parties.push(GroupBuilder{name:record[5].to_string(), abbreviation:None, group_id:group_id.to_string(),ticket_id:if position_in_ticket==0 {Some(candidate_id.to_string())} else {None}, tickets: vec![] });
                }
                if position_in_ticket!=0 { // real candidate.
                    // self.candidate_by_id.insert(candidate_id.to_string(),CandidateIndex(self.candidates.len()));
                    builder.candidates.push(Candidate{
                        name: record[4].to_string(),
                        party: Some(PartyIndex(builder.parties.len()-1)),
                        position: Some(position_in_ticket),
                        ec_id: Some(candidate_id.to_string()),
                    })
                }
            }
        }
    }
    Ok(())
}
/// the candidate information file doesn't list the place on the ticket.
/// the SenateFirstPrefsByStateByVoteTypeDownload file does, but it isn't available until after the election.
/// the file that is available before the election is not available well after the election :-)
/// so need to be able to parse both.
/// This format is used in 2016 and 2019
the candidate information file doesn't list the place on the ticket.
the SenateFirstPrefsByStateByVoteTypeDownload file does, but it isn't available until after the election.
the file that is available before the election is not available well after the election :-)
so need to be able to parse both.
This format is used in 2016 and 2019
the candidate information file doesn ' t list the place on the ticket . the SenateFirstPrefsByStateByVoteTypeDownload file does but it isn ' t available until after the election . the file that is available before the election is not available well after the election : - ) so need to be able to parse both . This format is used in 2016 and 2019
fn read_from_senate_first_prefs_by_state_by_vote_typ_download_file2016(builder: &mut CandidateAndGroupInformationBuilder,path:&Path,state:&str) -> anyhow::Result<()> {
    let mut rdr = csv::Reader::from_reader(skip_first_line_of_file(path)?);
    for result in rdr.records() {
        let record = result?;
        if state==&record[0] { // right state
            let group_id = &record[1]; // something like A, B, or UG
            let candidate_id = &record[2]; // something like 32847
            if candidate_id!="0" {
                let position_in_ticket = record[3].parse::<usize>()?; // 0, 1, .. 0 means a dummy id for the group ticket.
                if builder.parties.len()==0 || &builder.parties[builder.parties.len()-1].group_id != group_id {
                    builder.parties.push(GroupBuilder{name:record[5].to_string(), abbreviation:None, group_id:group_id.to_string(),ticket_id:if position_in_ticket==0 {Some(candidate_id.to_string())} else {None}, tickets: vec![] });
                }
                if position_in_ticket!=0 { // real candidate.
                    // self.candidate_by_id.insert(candidate_id.to_string(),CandidateIndex(self.candidates.len()));
                    builder.candidates.push(Candidate{
                        name: record[4].to_string(),
                        party: Some(PartyIndex(builder.parties.len()-1)),
                        position: Some(position_in_ticket),
                        ec_id: Some(candidate_id.to_string()),
                    })
                }
            }
        }
    }
    Ok(())
}
fn read_from_senate_first_prefs_by_state_by_vote_typ_download_file2016 ( builder : & mut CandidateAndGroupInformationBuilder , path : & Path , state : & str ) -> anyhow :: Result < ( ) > { let mut rdr = csv :: Reader :: from_reader ( skip_first_line_of_file ( path ) ? ) ; for result in rdr . records ( ) { let record = result ? ; if state == & record [ 0 ] { // right state let group_id = & record [ 1 ] ; // something like A, B, or UG let candidate_id = & record [ 2 ] ; // something like 32847 if candidate_id != " " { let position_in_ticket = record [ 3 ] . parse :: < usize > ( ) ? ; // 0, 1, .. 0 means a dummy id for the group ticket. if builder . parties . len ( ) == 0 || & builder . parties [ builder . parties . len ( ) - 1 ] . group_id != group_id { builder . parties . push ( GroupBuilder { name : record [ 5 ] . to_string ( ) , abbreviation : None , group_id : group_id . to_string ( ) , ticket_id : if position_in_ticket == 0 { Some ( candidate_id . to_string ( ) ) } else { None } , tickets : vec ! [ ] } ) ; } if position_in_ticket != 0 { // real candidate. // self.candidate_by_id.insert(candidate_id.to_string(),CandidateIndex(self.candidates.len())); builder . candidates . push ( Candidate { name : record [ 4 ] . to_string ( ) , party : Some ( PartyIndex ( builder . parties . len ( ) - 1 ) ) , position : Some ( position_in_ticket ) , ec_id : Some ( candidate_id . to_string ( ) ) , } ) } } } } Ok ( ( ) ) }
the candidate information file doesn't list the place on the ticket.
the candidate information file doesn ' t list the place on the ticket .
builder
&mut CandidateAndGroupInformationBuilder
path
&Path
state
&str
builder
&mut CandidateAndGroupInformationBuilder
path
&Path
state
&str