//! 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, Default, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] #[serde(rename_all = "snake_case")] pub enum VotingMethod { /// Simple approval voting (vote for multiple options) #[default] Approval, /// Ranked choice / instant runoff RankedChoice, /// Schulze method (Condorcet) Schulze, /// STAR voting (Score Then Automatic Runoff) Star, /// Quadratic voting (intensity-weighted) Quadratic, } 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, /// Full ranking of options pub ranking: Vec, /// 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, eliminated: Vec, }, Schulze { pairwise_matrix: Vec>, strongest_paths: Vec>, option_ids: Vec, }, 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, }