improve ballot parse function
This commit is contained in:
parent
4645cb31ee
commit
99724e5504
|
|
@ -22,54 +22,47 @@ pub struct Ballot {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Ballot {
|
impl Ballot {
|
||||||
pub fn parse_rows<T: std::io::BufRead>(csv: quick_csv::Csv<T>, header: &Header) -> Result<Vec<Ballot>, Box<dyn std::error::Error>> {
|
pub fn parse(row: quick_csv::Row, header: &Header) -> Result<Ballot, Box<dyn std::error::Error>> {
|
||||||
let mut ballots = Vec::<Self>::new();
|
let mut cols = row.columns()?;
|
||||||
|
|
||||||
|
let (state, division, collection_point, collection_point_id, batch_id, paper_id) = cols.next_tuple().ok_or("Missing columns")?;
|
||||||
|
let cols = cols.collect_vec();
|
||||||
|
let mut votes: Vec<Option<usize>>;
|
||||||
|
let ty: BallotType;
|
||||||
|
|
||||||
let col_filter = |(index, place): (usize, &str)| match place.parse::<usize>() {
|
let col_filter = |(index, place): (usize, &str)| match place.parse::<usize>() {
|
||||||
Ok(v) => Some((index, v - 1)),
|
Ok(v) => Some((index, v - 1)),
|
||||||
Err(_) => None,
|
Err(_) => None,
|
||||||
};
|
};
|
||||||
|
|
||||||
for result in csv {
|
// below the line votes
|
||||||
let row = result?;
|
if cols.len() > header.parties.len() {
|
||||||
let mut cols = row.columns()?;
|
ty = BallotType::Candidate;
|
||||||
|
votes = vec![None; header.candidates.len()];
|
||||||
let (state, division, collection_point, collection_point_id, batch_id, paper_id) = cols.next_tuple().ok_or("Missing columns")?;
|
for (col_id, place) in cols.iter().copied().skip(header.parties.len()).take(header.candidates.len()).enumerate().filter_map(col_filter) {
|
||||||
let cols = cols.collect_vec();
|
votes[place] = Some(col_id);
|
||||||
let mut votes: Vec<Option<usize>>;
|
|
||||||
let ty: BallotType;
|
|
||||||
|
|
||||||
// below the line votes
|
|
||||||
if cols.len() > header.parties.len() {
|
|
||||||
ty = BallotType::Candidate;
|
|
||||||
votes = vec![None; header.candidates.len()];
|
|
||||||
for (col_id, place) in cols.iter().copied().skip(header.parties.len()).take(header.candidates.len()).enumerate().filter_map(col_filter) {
|
|
||||||
votes[place] = Some(col_id);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// above the line votes
|
|
||||||
else {
|
|
||||||
ty = BallotType::Party;
|
|
||||||
votes = vec![None; header.parties.len()];
|
|
||||||
for (col_id, place) in cols.iter().copied().take(header.parties.len()).enumerate().filter_map(col_filter) {
|
|
||||||
votes[place] = Some(col_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ballots.push(Ballot {
|
|
||||||
state: state.to_owned(),
|
|
||||||
division: division.to_owned(),
|
|
||||||
collection_point: collection_point.to_owned(),
|
|
||||||
collection_point_id: collection_point_id.parse()?,
|
|
||||||
batch_id: batch_id.parse()?,
|
|
||||||
paper_id: paper_id.parse()?,
|
|
||||||
votes: votes.iter().copied().filter_map(|v| v).collect(),
|
|
||||||
ty,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(ballots)
|
// above the line votes
|
||||||
|
else {
|
||||||
|
ty = BallotType::Party;
|
||||||
|
votes = vec![None; header.parties.len()];
|
||||||
|
for (col_id, place) in cols.iter().copied().take(header.parties.len()).enumerate().filter_map(col_filter) {
|
||||||
|
votes[place] = Some(col_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(Ballot {
|
||||||
|
state: state.to_owned(),
|
||||||
|
division: division.to_owned(),
|
||||||
|
collection_point: collection_point.to_owned(),
|
||||||
|
collection_point_id: collection_point_id.parse()?,
|
||||||
|
batch_id: batch_id.parse()?,
|
||||||
|
paper_id: paper_id.parse()?,
|
||||||
|
votes: votes.iter().copied().filter_map(|v| v).collect(),
|
||||||
|
ty,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,11 @@ pub struct Counter {
|
||||||
impl Counter {
|
impl Counter {
|
||||||
pub fn new<T: std::io::BufRead>(mut csv: quick_csv::Csv<T>) -> Result<Self, Box<dyn std::error::Error>> {
|
pub fn new<T: std::io::BufRead>(mut csv: quick_csv::Csv<T>) -> Result<Self, Box<dyn std::error::Error>> {
|
||||||
let header = Header::parse(csv.next().ok_or("csv header missing")??)?;
|
let header = Header::parse(csv.next().ok_or("csv header missing")??)?;
|
||||||
let ballots = Ballot::parse_rows(csv, &header)?;
|
let mut ballots = Vec::new();
|
||||||
|
|
||||||
|
for row in csv {
|
||||||
|
ballots.push(Ballot::parse(row?, &header)?);
|
||||||
|
}
|
||||||
|
|
||||||
Ok(Counter {
|
Ok(Counter {
|
||||||
header,
|
header,
|
||||||
|
|
@ -18,5 +22,6 @@ impl Counter {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,7 @@
|
||||||
use std::env;
|
use std::env;
|
||||||
|
|
||||||
use ballot::{Ballot, BallotType};
|
use ballot::BallotType;
|
||||||
use counter::Counter;
|
use counter::Counter;
|
||||||
use header::Header;
|
|
||||||
|
|
||||||
pub mod candidate;
|
pub mod candidate;
|
||||||
pub mod ballot;
|
pub mod ballot;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue