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}