Fix crash on attempting segmented exclusion of candidate with no votes

This commit is contained in:
RunasSudo 2021-07-19 18:35:23 +10:00
parent d144ab0cb4
commit 7f16090395
No known key found for this signature in database
GPG Key ID: 7234E476BF21C61A
1 changed files with 49 additions and 37 deletions

View File

@ -391,42 +391,49 @@ where
} }
ExclusionMethod::ByValue => { ExclusionMethod::ByValue => {
// Exclude by value // Exclude by value
let max_value = excluded_candidates.iter() let excluded_with_votes: Vec<&&Candidate> = excluded_candidates.iter().filter(|c| !state.candidates[*c].parcels.is_empty()).collect();
.map(|c| state.candidates[c].parcels.iter()
.map(|p| p.iter().map(|v| &v.value / &v.ballot.orig_value).max().unwrap())
.max().unwrap())
.max().unwrap();
votes_remain = false; if excluded_with_votes.is_empty() {
votes_remain = false;
for excluded_candidate in excluded_candidates.iter() { } else {
let count_card = state.candidates.get_mut(excluded_candidate).unwrap(); // If candidates to exclude still having votes, select only those with the greatest value
let max_value = excluded_with_votes.iter()
.map(|c| state.candidates[*c].parcels.iter()
.map(|p| p.iter().map(|v| &v.value / &v.ballot.orig_value).max().unwrap())
.max().unwrap())
.max().unwrap();
// Filter out just those votes with max_value votes_remain = false;
let mut remaining_votes = Vec::new();
let cand_votes = count_card.parcels.concat(); for excluded_candidate in excluded_with_votes.iter() {
let count_card = state.candidates.get_mut(*excluded_candidate).unwrap();
let mut votes_transferred = N::new();
for vote in cand_votes.into_iter() { // Filter out just those votes with max_value
if &vote.value / &vote.ballot.orig_value == max_value { let mut remaining_votes = Vec::new();
votes_transferred += &vote.value;
votes.push(vote); let cand_votes = count_card.parcels.concat();
} else {
remaining_votes.push(vote); let mut votes_transferred = N::new();
for vote in cand_votes.into_iter() {
if &vote.value / &vote.ballot.orig_value == max_value {
votes_transferred += &vote.value;
votes.push(vote);
} else {
remaining_votes.push(vote);
}
} }
if !remaining_votes.is_empty() {
votes_remain = true;
}
// Leave remaining votes with candidate (as one parcel)
count_card.parcels = vec![remaining_votes];
// Update votes
checksum -= &votes_transferred;
count_card.transfer(&-votes_transferred);
} }
if !remaining_votes.is_empty() {
votes_remain = true;
}
// Leave remaining votes with candidate (as one parcel)
count_card.parcels = vec![remaining_votes];
// Update votes
checksum -= &votes_transferred;
count_card.transfer(&-votes_transferred);
} }
} }
ExclusionMethod::ParcelsByOrder => { ExclusionMethod::ParcelsByOrder => {
@ -436,13 +443,18 @@ where
} }
let count_card = state.candidates.get_mut(excluded_candidates[0]).unwrap(); let count_card = state.candidates.get_mut(excluded_candidates[0]).unwrap();
votes = count_card.parcels.remove(0);
votes_remain = !count_card.parcels.is_empty();
// Update votes if count_card.parcels.is_empty() {
let votes_transferred = votes.iter().fold(N::new(), |acc, v| acc + &v.value); votes_remain = false;
checksum -= &votes_transferred; } else {
count_card.transfer(&-votes_transferred); votes = count_card.parcels.remove(0);
votes_remain = !count_card.parcels.is_empty();
// Update votes
let votes_transferred = votes.iter().fold(N::new(), |acc, v| acc + &v.value);
checksum -= &votes_transferred;
count_card.transfer(&-votes_transferred);
}
} }
_ => panic!() _ => panic!()
} }