ic_query/sns/report/model/reports/proposals/row/
mod.rs1use serde::{Deserialize as SerdeDeserialize, Deserializer, Serialize};
8use std::borrow::Cow;
9
10#[must_use]
12pub fn sns_proposal_action_label(id: u64) -> Cow<'static, str> {
13 match id {
14 0 => Cow::Borrowed("unspecified"),
15 1 => Cow::Borrowed("motion"),
16 2 => Cow::Borrowed("manage_nervous_system_parameters"),
17 3 => Cow::Borrowed("upgrade_sns_controlled_canister"),
18 4 => Cow::Borrowed("add_generic_nervous_system_function"),
19 5 => Cow::Borrowed("remove_generic_nervous_system_function"),
20 6 => Cow::Borrowed("execute_generic_nervous_system_function"),
21 7 => Cow::Borrowed("upgrade_sns_to_next_version"),
22 8 => Cow::Borrowed("manage_sns_metadata"),
23 9 => Cow::Borrowed("transfer_sns_treasury_funds"),
24 10 => Cow::Borrowed("register_dapp_canisters"),
25 11 => Cow::Borrowed("deregister_dapp_canisters"),
26 12 => Cow::Borrowed("mint_sns_tokens"),
27 13 => Cow::Borrowed("manage_ledger_parameters"),
28 14 => Cow::Borrowed("manage_dapp_canister_settings"),
29 15 => Cow::Borrowed("advance_sns_target_version"),
30 16 => Cow::Borrowed("set_topics_for_custom_proposals"),
31 17 => Cow::Borrowed("register_extension"),
32 18 => Cow::Borrowed("execute_extension_operation"),
33 19 => Cow::Borrowed("upgrade_extension"),
34 id if id >= 1_000 => Cow::Owned(format!("generic:{id}")),
35 id => Cow::Owned(format!("unknown:{id}")),
36 }
37}
38
39#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd, SerdeDeserialize, Serialize)]
46#[serde(rename_all = "snake_case")]
47pub enum SnsProposalDecisionState {
48 Open,
50 Decided,
52 Executed,
54 Failed,
56}
57
58impl SnsProposalDecisionState {
59 #[must_use]
61 pub const fn as_str(self) -> &'static str {
62 match self {
63 Self::Open => "open",
64 Self::Decided => "decided",
65 Self::Executed => "executed",
66 Self::Failed => "failed",
67 }
68 }
69}
70
71#[derive(Clone, Debug, Eq, PartialEq, SerdeDeserialize, Serialize)]
78#[serde(deny_unknown_fields)]
79pub struct SnsProposalRow {
80 pub proposal_id: u64,
81 pub action_id: u64,
82 pub title: String,
83 pub summary: String,
84 pub url: Option<String>,
85 #[serde(deserialize_with = "deserialize_required_option")]
86 pub status: Option<i32>,
87 #[serde(deserialize_with = "deserialize_required_option")]
88 pub topic: Option<String>,
89 pub reject_cost_e8s: u64,
90 pub proposal_creation_timestamp_seconds: u64,
91 pub decided_timestamp_seconds: Option<u64>,
92 pub executed_timestamp_seconds: Option<u64>,
93 pub failed_timestamp_seconds: Option<u64>,
94 pub failure_reason: Option<SnsProposalFailureReason>,
95 pub reward_event_round: u64,
96 pub reward_event_end_timestamp_seconds: Option<u64>,
97 pub is_eligible_for_rewards: bool,
98 pub latest_tally: Option<SnsProposalTally>,
99 pub ballots: Vec<SnsProposalBallotRow>,
100 pub payload_text_rendering: Option<String>,
101 pub proposer_neuron_id: Option<String>,
102}
103
104impl SnsProposalRow {
105 #[must_use]
107 pub const fn decision_state(&self) -> SnsProposalDecisionState {
108 if matches!(self.failed_timestamp_seconds, Some(1..)) {
109 SnsProposalDecisionState::Failed
110 } else if matches!(self.executed_timestamp_seconds, Some(1..)) {
111 SnsProposalDecisionState::Executed
112 } else if matches!(self.decided_timestamp_seconds, Some(1..)) {
113 SnsProposalDecisionState::Decided
114 } else {
115 SnsProposalDecisionState::Open
116 }
117 }
118
119 #[must_use]
121 pub const fn ballot_count(&self) -> usize {
122 self.ballots.len()
123 }
124}
125
126fn deserialize_required_option<'de, D, T>(deserializer: D) -> Result<Option<T>, D::Error>
127where
128 D: Deserializer<'de>,
129 T: SerdeDeserialize<'de>,
130{
131 Option::<T>::deserialize(deserializer)
132}
133
134#[derive(Clone, Debug, Eq, PartialEq, SerdeDeserialize, Serialize)]
141#[serde(deny_unknown_fields)]
142pub struct SnsProposalBallotRow {
143 pub neuron_id: String,
144 pub vote: i32,
145 pub cast_timestamp_seconds: u64,
146 pub voting_power: u64,
147}
148
149#[derive(Clone, Debug, Eq, PartialEq, SerdeDeserialize, Serialize)]
156pub struct SnsProposalFailureReason {
157 pub error_type: i32,
158 pub error_message: String,
159}
160
161#[derive(Clone, Debug, Eq, PartialEq, SerdeDeserialize, Serialize)]
168pub struct SnsProposalTally {
169 pub timestamp_seconds: u64,
170 pub yes: u64,
171 pub no: u64,
172 pub total: u64,
173}
174
175#[cfg(test)]
176mod tests;