Skip to main content

popsam_core/
model.rs

1use serde::{Deserialize, Serialize};
2
3/// Raw input text identified by a caller-provided ID.
4#[derive(Debug, Clone, Serialize, Deserialize)]
5pub struct InputRecord {
6    /// Stable caller-provided identifier for the record.
7    pub id: String,
8    /// Optional original text content.
9    #[serde(default)]
10    pub text: Option<String>,
11}
12
13/// Input record with a caller-provided embedding vector.
14#[derive(Debug, Clone, Serialize, Deserialize)]
15pub struct EmbeddedTextInput {
16    /// Stable caller-provided identifier for the record.
17    pub id: String,
18    /// Optional original text content.
19    #[serde(default)]
20    pub text: Option<String>,
21    /// Embedding vector for the record.
22    pub embedding: Vec<f32>,
23}
24
25/// Record returned by an embedding provider or included in an election result.
26#[derive(Debug, Clone, Serialize, Deserialize)]
27pub struct EmbeddedText {
28    /// Stable caller-provided identifier for the record.
29    pub id: String,
30    /// Optional original text content.
31    #[serde(default)]
32    pub text: Option<String>,
33    /// Normalized embedding vector for the record.
34    pub embedding: Vec<f32>,
35}
36
37/// Vote totals for a candidate in a single round.
38#[derive(Debug, Clone, Serialize, Deserialize)]
39pub struct CandidateRoundVotes {
40    /// Candidate identifier.
41    pub id: String,
42    /// Number of first-preference votes.
43    pub first_votes: u32,
44    /// Number of second-preference votes.
45    pub second_votes: u32,
46    /// Number of third-preference votes.
47    pub third_votes: u32,
48}
49
50/// Best round result reached by a candidate during the full election.
51#[derive(Debug, Clone, Serialize, Deserialize)]
52pub struct CandidateBestResult {
53    /// Candidate identifier.
54    pub id: String,
55    /// One-based round index within the full election.
56    pub full_round_index: usize,
57    /// Number of candidates still active at the start of that round.
58    pub active_candidates: usize,
59    /// One-based rank among active candidates in that round.
60    pub rank: usize,
61    /// Number of first-preference votes in that round.
62    pub first_votes: u32,
63    /// Number of second-preference votes in that round.
64    pub second_votes: u32,
65    /// Number of third-preference votes in that round.
66    pub third_votes: u32,
67}
68
69/// Summary of a reported round among the final `k` candidates.
70#[derive(Debug, Clone, Serialize, Deserialize)]
71pub struct RoundSummary {
72    /// One-based round index within the reported suffix of the election.
73    pub round_index: usize,
74    /// Number of candidates still active at the start of the round.
75    pub active_candidates: usize,
76    /// Candidate IDs eliminated at the end of the round.
77    pub eliminated_candidate_ids: Vec<String>,
78    /// Vote totals for all active candidates in that round.
79    pub votes: Vec<CandidateRoundVotes>,
80}
81
82/// Result of running the elimination algorithm on a collection of embeddings.
83#[derive(Debug, Clone, Serialize, Deserialize)]
84pub struct ElectionResult {
85    /// ID of the final surviving candidate.
86    pub winner_id: String,
87    /// IDs of the last `k` candidates, captured when reporting begins.
88    pub representative_ids: Vec<String>,
89    /// Full ranking from winner to first eliminated candidate.
90    pub all_ranked_ids: Vec<String>,
91    /// Reported round summaries for the final `k` rounds.
92    pub rounds: Vec<RoundSummary>,
93    /// Best round result reached by each candidate during the full election, ordered like `all_ranked_ids`.
94    pub candidate_best_results: Vec<CandidateBestResult>,
95    /// Normalized embeddings associated with the processed records.
96    pub embeddings: Vec<EmbeddedText>,
97}