likwid/backend/src/voting/mod.rs

108 lines
2.9 KiB
Rust
Raw Normal View History

//! Advanced Voting Methods
//!
//! Implements various voting algorithms as described in the Democracy Design manifesto:
//! - Schulze Method (Condorcet-consistent pairwise comparison)
//! - STAR Voting (Score Then Automatic Runoff)
//! - Quadratic Voting (intensity-weighted preferences)
//! - Ranked Choice / Instant Runoff
pub mod schulze;
pub mod star;
pub mod quadratic;
pub mod ranked_choice;
use serde::{Deserialize, Serialize};
use uuid::Uuid;
/// Voting method types
/// Used by voting calculation services when tallying results.
#[allow(dead_code)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum VotingMethod {
/// Simple approval voting (vote for multiple options)
Approval,
/// Ranked choice / instant runoff
RankedChoice,
/// Schulze method (Condorcet)
Schulze,
/// STAR voting (Score Then Automatic Runoff)
Star,
/// Quadratic voting (intensity-weighted)
Quadratic,
}
impl Default for VotingMethod {
fn default() -> Self {
Self::Approval
}
}
impl std::fmt::Display for VotingMethod {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
VotingMethod::Approval => write!(f, "approval"),
VotingMethod::RankedChoice => write!(f, "ranked_choice"),
VotingMethod::Schulze => write!(f, "schulze"),
VotingMethod::Star => write!(f, "star"),
VotingMethod::Quadratic => write!(f, "quadratic"),
}
}
}
/// Result of a voting calculation
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct VotingResult {
/// The winning option (if any)
pub winner: Option<Uuid>,
/// Full ranking of options
pub ranking: Vec<RankedOption>,
/// Method-specific details
pub details: VotingDetails,
/// Total number of ballots counted
pub total_ballots: usize,
}
/// An option with its rank and score
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RankedOption {
pub option_id: Uuid,
pub rank: usize,
pub score: f64,
}
/// Method-specific voting details
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "method")]
pub enum VotingDetails {
Approval {
vote_counts: Vec<(Uuid, i64)>,
},
RankedChoice {
rounds: Vec<RoundResult>,
eliminated: Vec<Uuid>,
},
Schulze {
pairwise_matrix: Vec<Vec<i32>>,
strongest_paths: Vec<Vec<i32>>,
option_ids: Vec<Uuid>,
},
Star {
score_totals: Vec<(Uuid, i64)>,
finalists: (Uuid, Uuid),
runoff_votes: (i64, i64),
},
Quadratic {
vote_totals: Vec<(Uuid, i64)>,
total_credits_spent: i64,
},
}
/// Result of a single round in ranked choice voting
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RoundResult {
pub round: usize,
pub vote_counts: Vec<(Uuid, i64)>,
pub eliminated: Option<Uuid>,
}