1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
//! Common types
///Errors which may happen during the election
pub enum ElectionError {
///Scores got too large to fit in 64-bit integers
ArithmeticOverflow,
///Too many digits requested for fixed-point operation to fit in 64-bit integers
FixedPointDigitsTooMany,
///The election graph got degenerated and there is no single winner
DegeneratedElectionGraph,
///There is not enough candidates to fill all seats
NotEnoughCandidates,
}
use std::error::Error;
impl Error for ElectionError {}
use std::fmt;
impl fmt::Debug for ElectionError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self)
}
}
impl fmt::Display for ElectionError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use self::ElectionError::*;
match self {
FixedPointDigitsTooMany => write!(f, "Too many fixed-point digits"),
DegeneratedElectionGraph => write!(f, "Beat graph is degenerated"),
NotEnoughCandidates => write!(f, "Not enough candidates or votes"),
ArithmeticOverflow => write!(f, "Arithmetic overflow"),
}
}
}
#[derive(Copy, Clone)]
///Method of scoring candidates in pair comparisons
pub enum PairScore {
///Winning votes; winner gets score equal to votes for them, looser gets 0.
Winning,
///Margin of votes; winner gets winner votes - looser votes, looser gets looser votes - winner
///votes (that is, - winner score).
Margin,
///Opposition; both winner and looser get their votes.
Opposition,
}
#[derive(Copy, Clone)]
///Quota calculation method
pub enum Quota {
///[Hare quota](https://en.wikipedia.org/wiki/Hare_quota), that is useful votes / number of seats.
///Favours vote transfers, proportionality and diversity.
Hare,
///Floor of the `Hare` value
HareInt,
///[Droop quota](https://en.wikipedia.org/wiki/Droop_quota), that is floor( useful votes / ( seats + 1 ) ) + 1 vote.
///Favours first preferences, parties and secures majorities.
Droop,
///[Hagenbach-Bischoff quota](https://en.wikipedia.org/wiki/Hagenbach-Bischoff_quota), that is useful votes / ( seats + 1 ).
///Similar to Droop, secures majorities perfectly.
HagenbachBischoff,
}
#[derive(Clone, Copy)]
///Kind of a formula for scoring votes at different ranks
pub enum BordaKind {
///max_rank for first, 0 for last (1 for first if max_rank is 0)
Borda0,
///max_rank+1 for first, 1 for last
Borda1,
///1 for first, 1/(max_rank+1) for last; in practice multiplied by lcm(1,2,..,max_rank+1) so that all scores are integers
Nauru,
}
#[derive(Clone, Copy)]
///Schwarz or Smith set selector
pub enum SetType {
/// Smith set
Smith,
/// Schwartz set
Schwartz,
}
#[doc(inline)]
pub use crate::tally::Transfer;
pub use crate::outcome::Outcome;
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn election_error_msg() {
assert_eq!(
format!("{:?}", ElectionError::ArithmeticOverflow),
"Arithmetic overflow"
);
assert_eq!(
format!("{:?}", ElectionError::FixedPointDigitsTooMany),
"Too many fixed-point digits"
);
assert_eq!(
format!("{:?}", ElectionError::NotEnoughCandidates),
"Not enough candidates or votes"
);
assert_eq!(
format!("{:?}", ElectionError::DegeneratedElectionGraph),
"Beat graph is degenerated"
);
}
}