Skip to main content

ic_query/sns/report/model/reports/proposals/
row.rs

1//! Module: sns::report::model::reports::proposals::row
2//!
3//! Responsibility: define SNS proposal row and nested value DTOs.
4//! Does not own: source conversion, report-level metadata, or rendering.
5//! Boundary: preserves proposal detail fields for cache snapshots and JSON output.
6
7use serde::{Deserialize as SerdeDeserialize, Deserializer, Serialize};
8
9#[cfg(feature = "host")]
10pub(in crate::sns::report) const SNS_PROPOSAL_DECISION_DECIDED: &str = "decided";
11#[cfg(feature = "host")]
12pub(in crate::sns::report) const SNS_PROPOSAL_DECISION_EXECUTED: &str = "executed";
13#[cfg(feature = "host")]
14pub(in crate::sns::report) const SNS_PROPOSAL_DECISION_FAILED: &str = "failed";
15#[cfg(feature = "host")]
16pub(in crate::sns::report) const SNS_PROPOSAL_DECISION_OPEN: &str = "open";
17
18///
19/// SnsProposalRow
20///
21/// Serializable row for one SNS governance proposal.
22///
23
24#[derive(Clone, Debug, Eq, PartialEq, SerdeDeserialize, Serialize)]
25pub struct SnsProposalRow {
26    pub proposal_id: u64,
27    pub action_id: u64,
28    pub action: String,
29    pub title: String,
30    pub summary: String,
31    pub url: Option<String>,
32    pub decision_state: String,
33    #[serde(deserialize_with = "deserialize_required_option")]
34    pub status: Option<i32>,
35    #[serde(deserialize_with = "deserialize_required_option")]
36    pub topic: Option<String>,
37    pub reject_cost_e8s: u64,
38    pub proposal_creation_timestamp_seconds: u64,
39    pub created_at: String,
40    pub decided_timestamp_seconds: Option<u64>,
41    pub decided_at: Option<String>,
42    pub executed_timestamp_seconds: Option<u64>,
43    pub executed_at: Option<String>,
44    pub failed_timestamp_seconds: Option<u64>,
45    pub failed_at: Option<String>,
46    pub failure_reason: Option<SnsProposalFailureReason>,
47    pub reward_event_round: u64,
48    pub reward_event_end_timestamp_seconds: Option<u64>,
49    pub is_eligible_for_rewards: bool,
50    pub latest_tally: Option<SnsProposalTally>,
51    pub ballot_count: usize,
52    pub ballots: Vec<SnsProposalBallotRow>,
53    pub payload_text_rendering: Option<String>,
54    pub proposer_neuron_id: Option<String>,
55}
56
57fn deserialize_required_option<'de, D, T>(deserializer: D) -> Result<Option<T>, D::Error>
58where
59    D: Deserializer<'de>,
60    T: SerdeDeserialize<'de>,
61{
62    Option::<T>::deserialize(deserializer)
63}
64
65///
66/// SnsProposalBallotRow
67///
68/// Serializable row for one proposal ballot.
69///
70
71#[derive(Clone, Debug, Eq, PartialEq, SerdeDeserialize, Serialize)]
72pub struct SnsProposalBallotRow {
73    pub neuron_id: String,
74    pub vote: i32,
75    pub vote_text: String,
76    pub cast_timestamp_seconds: u64,
77    pub cast_at: Option<String>,
78    pub voting_power: u64,
79}
80
81///
82/// SnsProposalFailureReason
83///
84/// Serializable SNS governance failure reason attached to a proposal.
85///
86
87#[derive(Clone, Debug, Eq, PartialEq, SerdeDeserialize, Serialize)]
88pub struct SnsProposalFailureReason {
89    pub error_type: i32,
90    pub error_message: String,
91}
92
93///
94/// SnsProposalTally
95///
96/// Serializable SNS proposal vote tally.
97///
98
99#[derive(Clone, Debug, Eq, PartialEq, SerdeDeserialize, Serialize)]
100pub struct SnsProposalTally {
101    pub timestamp_seconds: u64,
102    pub yes: u64,
103    pub no: u64,
104    pub total: u64,
105}