Skip to main content

ic_query/nns/proposals/report/
model.rs

1//! Module: nns::proposals::report::model
2//!
3//! Responsibility: NNS proposal request and report DTOs.
4//! Does not own: live governance transport, command parsing, or text rendering.
5//! Boundary: defines stable JSON shapes for NNS proposal output.
6
7use serde::{Deserialize, Serialize};
8
9pub(in crate::nns) const NNS_PROPOSAL_SORT_API_LABEL: &str = "api";
10pub(in crate::nns) const NNS_PROPOSAL_SORT_ID_LABEL: &str = "id";
11pub(in crate::nns) const NNS_PROPOSAL_SORT_STATUS_LABEL: &str = "status";
12pub(in crate::nns) const NNS_PROPOSAL_SORT_REWARD_STATUS_LABEL: &str = "reward-status";
13pub(in crate::nns) const NNS_PROPOSAL_SORT_TOPIC_LABEL: &str = "topic";
14pub(in crate::nns) const NNS_PROPOSAL_SORT_PROPOSER_LABEL: &str = "proposer";
15pub(in crate::nns) const NNS_PROPOSAL_SORT_TITLE_LABEL: &str = "title";
16pub(in crate::nns) const NNS_PROPOSAL_SORT_ACTION_LABEL: &str = "action";
17pub(in crate::nns) const NNS_PROPOSAL_SORT_YES_LABEL: &str = "yes";
18pub(in crate::nns) const NNS_PROPOSAL_SORT_NO_LABEL: &str = "no";
19pub(in crate::nns) const NNS_PROPOSAL_SORT_TOTAL_VOTES_LABEL: &str = "total-votes";
20pub(in crate::nns) const NNS_PROPOSAL_SORT_TALLY_TIME_LABEL: &str = "tally-time";
21pub(in crate::nns) const NNS_PROPOSAL_SORT_VOTING_POWER_LABEL: &str = "voting-power";
22pub(in crate::nns) const NNS_PROPOSAL_SORT_BALLOTS_LABEL: &str = "ballots";
23pub(in crate::nns) const NNS_PROPOSAL_SORT_REJECT_COST_LABEL: &str = "reject-cost";
24pub(in crate::nns) const NNS_PROPOSAL_SORT_REWARD_ROUND_LABEL: &str = "reward-round";
25pub(in crate::nns) const NNS_PROPOSAL_SORT_PROPOSED_LABEL: &str = "proposed";
26pub(in crate::nns) const NNS_PROPOSAL_SORT_DEADLINE_LABEL: &str = "deadline";
27pub(in crate::nns) const NNS_PROPOSAL_SORT_DECIDED_LABEL: &str = "decided";
28pub(in crate::nns) const NNS_PROPOSAL_SORT_EXECUTED_LABEL: &str = "executed";
29pub(in crate::nns) const NNS_PROPOSAL_SORT_FAILED_LABEL: &str = "failed";
30pub(in crate::nns) const NNS_PROPOSAL_SORT_ASC_LABEL: &str = "asc";
31pub(in crate::nns) const NNS_PROPOSAL_SORT_DESC_LABEL: &str = "desc";
32pub(in crate::nns) const NNS_PROPOSAL_SORT_NONE_LABEL: &str = "none";
33
34pub(in crate::nns) const NNS_PROPOSAL_STATUS_ANY_LABEL: &str = "any";
35pub(in crate::nns) const NNS_PROPOSAL_STATUS_OPEN_LABEL: &str = "open";
36pub(in crate::nns) const NNS_PROPOSAL_STATUS_REJECTED_LABEL: &str = "rejected";
37pub(in crate::nns) const NNS_PROPOSAL_STATUS_ADOPTED_LABEL: &str = "adopted";
38pub(in crate::nns) const NNS_PROPOSAL_STATUS_EXECUTED_LABEL: &str = "executed";
39pub(in crate::nns) const NNS_PROPOSAL_STATUS_FAILED_LABEL: &str = "failed";
40#[cfg(feature = "host")]
41pub(in crate::nns) const NNS_PROPOSAL_STATUS_UNSPECIFIED_LABEL: &str = "unspecified";
42#[cfg(feature = "host")]
43pub(in crate::nns) const NNS_PROPOSAL_STATUS_OPEN_CODE: i32 = 1;
44#[cfg(feature = "host")]
45pub(in crate::nns) const NNS_PROPOSAL_STATUS_REJECTED_CODE: i32 = 2;
46#[cfg(feature = "host")]
47pub(in crate::nns) const NNS_PROPOSAL_STATUS_ADOPTED_CODE: i32 = 3;
48#[cfg(feature = "host")]
49pub(in crate::nns) const NNS_PROPOSAL_STATUS_EXECUTED_CODE: i32 = 4;
50#[cfg(feature = "host")]
51pub(in crate::nns) const NNS_PROPOSAL_STATUS_FAILED_CODE: i32 = 5;
52
53pub(in crate::nns) const NNS_PROPOSAL_REWARD_STATUS_ACCEPT_VOTES_LABEL: &str = "accept-votes";
54pub(in crate::nns) const NNS_PROPOSAL_REWARD_STATUS_READY_TO_SETTLE_LABEL: &str = "ready-to-settle";
55pub(in crate::nns) const NNS_PROPOSAL_REWARD_STATUS_SETTLED_LABEL: &str = "settled";
56pub(in crate::nns) const NNS_PROPOSAL_REWARD_STATUS_INELIGIBLE_LABEL: &str = "ineligible";
57pub(in crate::nns) const NNS_PROPOSAL_REWARD_STATUS_ANY_LABEL: &str = "any";
58#[cfg(feature = "host")]
59pub(in crate::nns) const NNS_PROPOSAL_REWARD_STATUS_UNSPECIFIED_LABEL: &str = "unspecified";
60#[cfg(feature = "host")]
61pub(in crate::nns) const NNS_PROPOSAL_REWARD_STATUS_ACCEPT_VOTES_CODE: i32 = 1;
62#[cfg(feature = "host")]
63pub(in crate::nns) const NNS_PROPOSAL_REWARD_STATUS_READY_TO_SETTLE_CODE: i32 = 2;
64#[cfg(feature = "host")]
65pub(in crate::nns) const NNS_PROPOSAL_REWARD_STATUS_SETTLED_CODE: i32 = 3;
66#[cfg(feature = "host")]
67pub(in crate::nns) const NNS_PROPOSAL_REWARD_STATUS_INELIGIBLE_CODE: i32 = 4;
68
69#[cfg(feature = "host")]
70pub(in crate::nns) const NNS_PROPOSAL_VOTE_UNSPECIFIED_LABEL: &str = "unspecified";
71#[cfg(feature = "host")]
72pub(in crate::nns) const NNS_PROPOSAL_VOTE_YES_LABEL: &str = "yes";
73#[cfg(feature = "host")]
74pub(in crate::nns) const NNS_PROPOSAL_VOTE_NO_LABEL: &str = "no";
75#[cfg(feature = "host")]
76pub(in crate::nns) const NNS_PROPOSAL_VOTE_YES_CODE: i32 = 1;
77#[cfg(feature = "host")]
78pub(in crate::nns) const NNS_PROPOSAL_VOTE_NO_CODE: i32 = 2;
79
80pub(in crate::nns) const NNS_PROPOSAL_TOPIC_ANY_LABEL: &str = "any";
81pub(in crate::nns) const NNS_PROPOSAL_TOPIC_NEURON_MANAGEMENT_LABEL: &str = "neuron-management";
82pub(in crate::nns) const NNS_PROPOSAL_TOPIC_EXCHANGE_RATE_LABEL: &str = "exchange-rate";
83pub(in crate::nns) const NNS_PROPOSAL_TOPIC_NETWORK_ECONOMICS_LABEL: &str = "network-economics";
84pub(in crate::nns) const NNS_PROPOSAL_TOPIC_GOVERNANCE_LABEL: &str = "governance";
85pub(in crate::nns) const NNS_PROPOSAL_TOPIC_NODE_ADMIN_LABEL: &str = "node-admin";
86pub(in crate::nns) const NNS_PROPOSAL_TOPIC_PARTICIPANT_MANAGEMENT_LABEL: &str =
87    "participant-management";
88pub(in crate::nns) const NNS_PROPOSAL_TOPIC_SUBNET_MANAGEMENT_LABEL: &str = "subnet-management";
89pub(in crate::nns) const NNS_PROPOSAL_TOPIC_NETWORK_CANISTER_MANAGEMENT_LABEL: &str =
90    "network-canister-management";
91pub(in crate::nns) const NNS_PROPOSAL_TOPIC_KYC_LABEL: &str = "kyc";
92pub(in crate::nns) const NNS_PROPOSAL_TOPIC_NODE_PROVIDER_REWARDS_LABEL: &str =
93    "node-provider-rewards";
94pub(in crate::nns) const NNS_PROPOSAL_TOPIC_IC_OS_VERSION_DEPLOYMENT_LABEL: &str =
95    "ic-os-version-deployment";
96pub(in crate::nns) const NNS_PROPOSAL_TOPIC_IC_OS_VERSION_ELECTION_LABEL: &str =
97    "ic-os-version-election";
98pub(in crate::nns) const NNS_PROPOSAL_TOPIC_SNS_AND_COMMUNITY_FUND_LABEL: &str =
99    "sns-and-community-fund";
100pub(in crate::nns) const NNS_PROPOSAL_TOPIC_API_BOUNDARY_NODE_MANAGEMENT_LABEL: &str =
101    "api-boundary-node-management";
102pub(in crate::nns) const NNS_PROPOSAL_TOPIC_SUBNET_RENTAL_LABEL: &str = "subnet-rental";
103pub(in crate::nns) const NNS_PROPOSAL_TOPIC_APPLICATION_CANISTER_MANAGEMENT_LABEL: &str =
104    "application-canister-management";
105pub(in crate::nns) const NNS_PROPOSAL_TOPIC_PROTOCOL_CANISTER_MANAGEMENT_LABEL: &str =
106    "protocol-canister-management";
107#[cfg(feature = "host")]
108pub(in crate::nns) const NNS_PROPOSAL_TOPIC_UNSPECIFIED_LABEL: &str = "unspecified";
109#[cfg(feature = "host")]
110pub(in crate::nns) const NNS_PROPOSAL_TOPIC_NEURON_MANAGEMENT_CODE: i32 = 1;
111#[cfg(feature = "host")]
112pub(in crate::nns) const NNS_PROPOSAL_TOPIC_EXCHANGE_RATE_CODE: i32 = 2;
113#[cfg(feature = "host")]
114pub(in crate::nns) const NNS_PROPOSAL_TOPIC_NETWORK_ECONOMICS_CODE: i32 = 3;
115#[cfg(feature = "host")]
116pub(in crate::nns) const NNS_PROPOSAL_TOPIC_GOVERNANCE_CODE: i32 = 4;
117#[cfg(feature = "host")]
118pub(in crate::nns) const NNS_PROPOSAL_TOPIC_NODE_ADMIN_CODE: i32 = 5;
119#[cfg(feature = "host")]
120pub(in crate::nns) const NNS_PROPOSAL_TOPIC_PARTICIPANT_MANAGEMENT_CODE: i32 = 6;
121#[cfg(feature = "host")]
122pub(in crate::nns) const NNS_PROPOSAL_TOPIC_SUBNET_MANAGEMENT_CODE: i32 = 7;
123#[cfg(feature = "host")]
124pub(in crate::nns) const NNS_PROPOSAL_TOPIC_NETWORK_CANISTER_MANAGEMENT_CODE: i32 = 8;
125#[cfg(feature = "host")]
126pub(in crate::nns) const NNS_PROPOSAL_TOPIC_KYC_CODE: i32 = 9;
127#[cfg(feature = "host")]
128pub(in crate::nns) const NNS_PROPOSAL_TOPIC_NODE_PROVIDER_REWARDS_CODE: i32 = 10;
129#[cfg(feature = "host")]
130pub(in crate::nns) const NNS_PROPOSAL_TOPIC_IC_OS_VERSION_DEPLOYMENT_CODE: i32 = 12;
131#[cfg(feature = "host")]
132pub(in crate::nns) const NNS_PROPOSAL_TOPIC_IC_OS_VERSION_ELECTION_CODE: i32 = 13;
133#[cfg(feature = "host")]
134pub(in crate::nns) const NNS_PROPOSAL_TOPIC_SNS_AND_COMMUNITY_FUND_CODE: i32 = 14;
135#[cfg(feature = "host")]
136pub(in crate::nns) const NNS_PROPOSAL_TOPIC_API_BOUNDARY_NODE_MANAGEMENT_CODE: i32 = 15;
137#[cfg(feature = "host")]
138pub(in crate::nns) const NNS_PROPOSAL_TOPIC_SUBNET_RENTAL_CODE: i32 = 16;
139#[cfg(feature = "host")]
140pub(in crate::nns) const NNS_PROPOSAL_TOPIC_APPLICATION_CANISTER_MANAGEMENT_CODE: i32 = 17;
141#[cfg(feature = "host")]
142pub(in crate::nns) const NNS_PROPOSAL_TOPIC_PROTOCOL_CANISTER_MANAGEMENT_CODE: i32 = 18;
143
144///
145/// NnsProposalListRequest
146///
147/// Request accepted by the NNS proposal list report builder.
148///
149
150#[derive(Clone, Debug, Eq, PartialEq)]
151pub struct NnsProposalListRequest {
152    pub network: String,
153    pub source_endpoint: String,
154    pub now_unix_secs: u64,
155    pub limit: u32,
156    pub before_proposal_id: Option<u64>,
157    pub status: NnsProposalStatusFilter,
158    pub reward_status: NnsProposalRewardStatusFilter,
159    pub topic: NnsProposalTopicFilter,
160    pub proposer_neuron_id: Option<u64>,
161    pub query: Option<String>,
162    pub sort: NnsProposalListSort,
163    pub sort_direction: NnsProposalSortDirection,
164    pub verbose: bool,
165}
166
167impl NnsProposalListRequest {
168    #[must_use]
169    pub fn new(
170        network: impl Into<String>,
171        source_endpoint: impl Into<String>,
172        now_unix_secs: u64,
173        limit: u32,
174    ) -> Self {
175        Self {
176            network: network.into(),
177            source_endpoint: source_endpoint.into(),
178            now_unix_secs,
179            limit,
180            before_proposal_id: None,
181            status: NnsProposalStatusFilter::default(),
182            reward_status: NnsProposalRewardStatusFilter::default(),
183            topic: NnsProposalTopicFilter::default(),
184            proposer_neuron_id: None,
185            query: None,
186            sort: NnsProposalListSort::default(),
187            sort_direction: NnsProposalSortDirection::default(),
188            verbose: false,
189        }
190    }
191
192    #[must_use]
193    pub const fn with_before_proposal_id(mut self, before_proposal_id: u64) -> Self {
194        self.before_proposal_id = Some(before_proposal_id);
195        self
196    }
197
198    #[must_use]
199    pub const fn with_status(mut self, status: NnsProposalStatusFilter) -> Self {
200        self.status = status;
201        self
202    }
203
204    #[must_use]
205    pub const fn with_reward_status(
206        mut self,
207        reward_status: NnsProposalRewardStatusFilter,
208    ) -> Self {
209        self.reward_status = reward_status;
210        self
211    }
212
213    #[must_use]
214    pub const fn with_topic(mut self, topic: NnsProposalTopicFilter) -> Self {
215        self.topic = topic;
216        self
217    }
218
219    #[must_use]
220    pub const fn with_proposer_neuron_id(mut self, proposer_neuron_id: u64) -> Self {
221        self.proposer_neuron_id = Some(proposer_neuron_id);
222        self
223    }
224
225    #[must_use]
226    pub fn with_query(mut self, query: impl Into<String>) -> Self {
227        self.query = Some(query.into());
228        self
229    }
230
231    #[must_use]
232    pub const fn with_sort(mut self, sort: NnsProposalListSort) -> Self {
233        self.sort = sort;
234        self.sort_direction = sort.default_direction();
235        self
236    }
237
238    #[must_use]
239    pub const fn with_sort_direction(mut self, sort_direction: NnsProposalSortDirection) -> Self {
240        self.sort_direction = sort_direction;
241        self
242    }
243
244    #[must_use]
245    pub const fn with_verbose(mut self, verbose: bool) -> Self {
246        self.verbose = verbose;
247        self
248    }
249}
250
251///
252/// NnsProposalRequest
253///
254/// Request accepted by the NNS proposal detail report builder.
255///
256
257#[derive(Clone, Debug, Eq, PartialEq)]
258pub struct NnsProposalRequest {
259    pub network: String,
260    pub source_endpoint: String,
261    pub now_unix_secs: u64,
262    pub proposal_id: u64,
263    pub show_ballots: bool,
264    pub verbose: bool,
265}
266
267impl NnsProposalRequest {
268    #[must_use]
269    pub fn new(
270        network: impl Into<String>,
271        source_endpoint: impl Into<String>,
272        now_unix_secs: u64,
273        proposal_id: u64,
274    ) -> Self {
275        Self {
276            network: network.into(),
277            source_endpoint: source_endpoint.into(),
278            now_unix_secs,
279            proposal_id,
280            show_ballots: false,
281            verbose: false,
282        }
283    }
284
285    #[must_use]
286    pub const fn with_show_ballots(mut self, show_ballots: bool) -> Self {
287        self.show_ballots = show_ballots;
288        self
289    }
290
291    #[must_use]
292    pub const fn with_verbose(mut self, verbose: bool) -> Self {
293        self.verbose = verbose;
294        self
295    }
296}
297
298///
299/// NnsProposalListReport
300///
301/// Serializable report for a bounded NNS governance proposal listing.
302///
303
304#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
305pub struct NnsProposalListReport {
306    pub schema_version: u32,
307    pub network: String,
308    pub governance_canister_id: String,
309    pub fetched_at: String,
310    pub source_endpoint: String,
311    pub fetched_by: String,
312    pub data_source: String,
313    pub cache_path: Option<String>,
314    pub cache_complete: Option<bool>,
315    pub requested_limit: u32,
316    pub before_proposal_id: Option<u64>,
317    pub status_filter: String,
318    pub reward_status_filter: String,
319    pub topic_filter: String,
320    pub proposer_filter: Option<u64>,
321    pub query_filter: Option<String>,
322    pub sort: String,
323    pub sort_direction: String,
324    pub result_scope: String,
325    pub verbose: bool,
326    pub proposal_count: usize,
327    pub proposals: Vec<NnsProposalRow>,
328}
329
330///
331/// NnsProposalReport
332///
333/// Serializable report for one NNS governance proposal detail lookup.
334///
335
336#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
337pub struct NnsProposalReport {
338    pub schema_version: u32,
339    pub network: String,
340    pub governance_canister_id: String,
341    pub fetched_at: String,
342    pub source_endpoint: String,
343    pub fetched_by: String,
344    pub data_source: String,
345    pub cache_path: Option<String>,
346    pub cache_complete: Option<bool>,
347    pub proposal_id: u64,
348    pub show_ballots: bool,
349    pub verbose: bool,
350    pub proposal: NnsProposalRow,
351}
352
353///
354/// NnsProposalRow
355///
356/// Serializable row for one NNS governance proposal.
357///
358
359#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
360pub struct NnsProposalRow {
361    pub proposal_id: Option<u64>,
362    pub proposer_neuron_id: Option<u64>,
363    pub topic: i32,
364    pub topic_text: String,
365    pub status: i32,
366    pub status_text: String,
367    pub reward_status: i32,
368    pub reward_status_text: String,
369    pub title: Option<String>,
370    pub summary: String,
371    pub url: String,
372    pub action_text: Option<String>,
373    pub reject_cost_e8s: u64,
374    pub proposal_timestamp_seconds: u64,
375    pub proposed_at: String,
376    pub deadline_timestamp_seconds: Option<u64>,
377    pub deadline_at: Option<String>,
378    pub decided_timestamp_seconds: u64,
379    pub decided_at: Option<String>,
380    pub executed_timestamp_seconds: u64,
381    pub executed_at: Option<String>,
382    pub failed_timestamp_seconds: u64,
383    pub failed_at: Option<String>,
384    pub reward_event_round: u64,
385    pub total_potential_voting_power: Option<u64>,
386    pub latest_tally: Option<NnsProposalTally>,
387    pub ballot_count: usize,
388    pub ballots: Vec<NnsProposalBallotRow>,
389}
390
391///
392/// NnsProposalBallotRow
393///
394/// Serializable NNS proposal ballot row.
395///
396
397#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
398pub struct NnsProposalBallotRow {
399    pub neuron_id: u64,
400    pub vote: i32,
401    pub vote_text: String,
402    pub voting_power: u64,
403}
404
405///
406/// NnsProposalTally
407///
408/// Serializable NNS proposal vote tally.
409///
410
411#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
412pub struct NnsProposalTally {
413    pub timestamp_seconds: u64,
414    pub yes: u64,
415    pub no: u64,
416    pub total: u64,
417}
418
419///
420/// NnsProposalListSort
421///
422/// Report-model sort selector for NNS proposal listings.
423///
424
425#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
426pub enum NnsProposalListSort {
427    #[default]
428    Api,
429    Id,
430    Status,
431    RewardStatus,
432    Topic,
433    Proposer,
434    Title,
435    Action,
436    Yes,
437    No,
438    TotalVotes,
439    TallyTime,
440    VotingPower,
441    Ballots,
442    RejectCost,
443    RewardRound,
444    Proposed,
445    Deadline,
446    Decided,
447    Executed,
448    Failed,
449}
450
451impl NnsProposalListSort {
452    #[must_use]
453    pub const fn as_str(self) -> &'static str {
454        match self {
455            Self::Api => NNS_PROPOSAL_SORT_API_LABEL,
456            Self::Id => NNS_PROPOSAL_SORT_ID_LABEL,
457            Self::Status => NNS_PROPOSAL_SORT_STATUS_LABEL,
458            Self::RewardStatus => NNS_PROPOSAL_SORT_REWARD_STATUS_LABEL,
459            Self::Topic => NNS_PROPOSAL_SORT_TOPIC_LABEL,
460            Self::Proposer => NNS_PROPOSAL_SORT_PROPOSER_LABEL,
461            Self::Title => NNS_PROPOSAL_SORT_TITLE_LABEL,
462            Self::Action => NNS_PROPOSAL_SORT_ACTION_LABEL,
463            Self::Yes => NNS_PROPOSAL_SORT_YES_LABEL,
464            Self::No => NNS_PROPOSAL_SORT_NO_LABEL,
465            Self::TotalVotes => NNS_PROPOSAL_SORT_TOTAL_VOTES_LABEL,
466            Self::TallyTime => NNS_PROPOSAL_SORT_TALLY_TIME_LABEL,
467            Self::VotingPower => NNS_PROPOSAL_SORT_VOTING_POWER_LABEL,
468            Self::Ballots => NNS_PROPOSAL_SORT_BALLOTS_LABEL,
469            Self::RejectCost => NNS_PROPOSAL_SORT_REJECT_COST_LABEL,
470            Self::RewardRound => NNS_PROPOSAL_SORT_REWARD_ROUND_LABEL,
471            Self::Proposed => NNS_PROPOSAL_SORT_PROPOSED_LABEL,
472            Self::Deadline => NNS_PROPOSAL_SORT_DEADLINE_LABEL,
473            Self::Decided => NNS_PROPOSAL_SORT_DECIDED_LABEL,
474            Self::Executed => NNS_PROPOSAL_SORT_EXECUTED_LABEL,
475            Self::Failed => NNS_PROPOSAL_SORT_FAILED_LABEL,
476        }
477    }
478
479    #[must_use]
480    pub const fn default_direction(self) -> NnsProposalSortDirection {
481        match self {
482            Self::Status
483            | Self::RewardStatus
484            | Self::Topic
485            | Self::Proposer
486            | Self::Title
487            | Self::Action => NnsProposalSortDirection::Asc,
488            _ => NnsProposalSortDirection::Desc,
489        }
490    }
491
492    #[must_use]
493    pub const fn uses_local_direction(self) -> bool {
494        !matches!(self, Self::Api)
495    }
496
497    #[must_use]
498    pub const fn direction_label(self, direction: NnsProposalSortDirection) -> &'static str {
499        match self {
500            Self::Api => NNS_PROPOSAL_SORT_NONE_LABEL,
501            _ => direction.as_str(),
502        }
503    }
504}
505
506///
507/// NnsProposalSortDirection
508///
509/// Report-model direction selector for local NNS proposal sorting.
510///
511
512#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
513pub enum NnsProposalSortDirection {
514    Asc,
515    #[default]
516    Desc,
517}
518
519impl NnsProposalSortDirection {
520    #[must_use]
521    pub const fn as_str(self) -> &'static str {
522        match self {
523            Self::Asc => NNS_PROPOSAL_SORT_ASC_LABEL,
524            Self::Desc => NNS_PROPOSAL_SORT_DESC_LABEL,
525        }
526    }
527}
528
529///
530/// NnsProposalStatusFilter
531///
532/// Report-model status filter for bounded NNS proposal listings.
533///
534
535#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
536pub enum NnsProposalStatusFilter {
537    #[default]
538    Any,
539    Open,
540    Rejected,
541    Adopted,
542    Executed,
543    Failed,
544}
545
546///
547/// NnsProposalRewardStatusFilter
548///
549/// Report-model reward status filter for bounded NNS proposal listings.
550///
551
552#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
553pub enum NnsProposalRewardStatusFilter {
554    #[default]
555    Any,
556    AcceptVotes,
557    ReadyToSettle,
558    Settled,
559    Ineligible,
560}
561
562impl NnsProposalRewardStatusFilter {
563    #[must_use]
564    pub const fn as_str(self) -> &'static str {
565        match self {
566            Self::Any => NNS_PROPOSAL_REWARD_STATUS_ANY_LABEL,
567            Self::AcceptVotes => NNS_PROPOSAL_REWARD_STATUS_ACCEPT_VOTES_LABEL,
568            Self::ReadyToSettle => NNS_PROPOSAL_REWARD_STATUS_READY_TO_SETTLE_LABEL,
569            Self::Settled => NNS_PROPOSAL_REWARD_STATUS_SETTLED_LABEL,
570            Self::Ineligible => NNS_PROPOSAL_REWARD_STATUS_INELIGIBLE_LABEL,
571        }
572    }
573
574    #[cfg(feature = "host")]
575    pub(in crate::nns) const fn governance_reward_status_code(self) -> Option<i32> {
576        match self {
577            Self::Any => None,
578            Self::AcceptVotes => Some(NNS_PROPOSAL_REWARD_STATUS_ACCEPT_VOTES_CODE),
579            Self::ReadyToSettle => Some(NNS_PROPOSAL_REWARD_STATUS_READY_TO_SETTLE_CODE),
580            Self::Settled => Some(NNS_PROPOSAL_REWARD_STATUS_SETTLED_CODE),
581            Self::Ineligible => Some(NNS_PROPOSAL_REWARD_STATUS_INELIGIBLE_CODE),
582        }
583    }
584}
585
586impl NnsProposalStatusFilter {
587    #[must_use]
588    pub const fn as_str(self) -> &'static str {
589        match self {
590            Self::Any => NNS_PROPOSAL_STATUS_ANY_LABEL,
591            Self::Open => NNS_PROPOSAL_STATUS_OPEN_LABEL,
592            Self::Rejected => NNS_PROPOSAL_STATUS_REJECTED_LABEL,
593            Self::Adopted => NNS_PROPOSAL_STATUS_ADOPTED_LABEL,
594            Self::Executed => NNS_PROPOSAL_STATUS_EXECUTED_LABEL,
595            Self::Failed => NNS_PROPOSAL_STATUS_FAILED_LABEL,
596        }
597    }
598
599    #[cfg(feature = "host")]
600    pub(in crate::nns) const fn governance_status_code(self) -> Option<i32> {
601        match self {
602            Self::Any => None,
603            Self::Open => Some(NNS_PROPOSAL_STATUS_OPEN_CODE),
604            Self::Rejected => Some(NNS_PROPOSAL_STATUS_REJECTED_CODE),
605            Self::Adopted => Some(NNS_PROPOSAL_STATUS_ADOPTED_CODE),
606            Self::Executed => Some(NNS_PROPOSAL_STATUS_EXECUTED_CODE),
607            Self::Failed => Some(NNS_PROPOSAL_STATUS_FAILED_CODE),
608        }
609    }
610}
611
612///
613/// NnsProposalTopicFilter
614///
615/// Report-model topic filter for bounded NNS proposal listings.
616///
617
618#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
619pub enum NnsProposalTopicFilter {
620    #[default]
621    Any,
622    NeuronManagement,
623    ExchangeRate,
624    NetworkEconomics,
625    Governance,
626    NodeAdmin,
627    ParticipantManagement,
628    SubnetManagement,
629    NetworkCanisterManagement,
630    Kyc,
631    NodeProviderRewards,
632    IcOsVersionDeployment,
633    IcOsVersionElection,
634    SnsAndCommunityFund,
635    ApiBoundaryNodeManagement,
636    SubnetRental,
637    ApplicationCanisterManagement,
638    ProtocolCanisterManagement,
639}
640
641impl NnsProposalTopicFilter {
642    #[must_use]
643    pub const fn as_str(self) -> &'static str {
644        match self {
645            Self::Any => NNS_PROPOSAL_TOPIC_ANY_LABEL,
646            Self::NeuronManagement => NNS_PROPOSAL_TOPIC_NEURON_MANAGEMENT_LABEL,
647            Self::ExchangeRate => NNS_PROPOSAL_TOPIC_EXCHANGE_RATE_LABEL,
648            Self::NetworkEconomics => NNS_PROPOSAL_TOPIC_NETWORK_ECONOMICS_LABEL,
649            Self::Governance => NNS_PROPOSAL_TOPIC_GOVERNANCE_LABEL,
650            Self::NodeAdmin => NNS_PROPOSAL_TOPIC_NODE_ADMIN_LABEL,
651            Self::ParticipantManagement => NNS_PROPOSAL_TOPIC_PARTICIPANT_MANAGEMENT_LABEL,
652            Self::SubnetManagement => NNS_PROPOSAL_TOPIC_SUBNET_MANAGEMENT_LABEL,
653            Self::NetworkCanisterManagement => NNS_PROPOSAL_TOPIC_NETWORK_CANISTER_MANAGEMENT_LABEL,
654            Self::Kyc => NNS_PROPOSAL_TOPIC_KYC_LABEL,
655            Self::NodeProviderRewards => NNS_PROPOSAL_TOPIC_NODE_PROVIDER_REWARDS_LABEL,
656            Self::IcOsVersionDeployment => NNS_PROPOSAL_TOPIC_IC_OS_VERSION_DEPLOYMENT_LABEL,
657            Self::IcOsVersionElection => NNS_PROPOSAL_TOPIC_IC_OS_VERSION_ELECTION_LABEL,
658            Self::SnsAndCommunityFund => NNS_PROPOSAL_TOPIC_SNS_AND_COMMUNITY_FUND_LABEL,
659            Self::ApiBoundaryNodeManagement => {
660                NNS_PROPOSAL_TOPIC_API_BOUNDARY_NODE_MANAGEMENT_LABEL
661            }
662            Self::SubnetRental => NNS_PROPOSAL_TOPIC_SUBNET_RENTAL_LABEL,
663            Self::ApplicationCanisterManagement => {
664                NNS_PROPOSAL_TOPIC_APPLICATION_CANISTER_MANAGEMENT_LABEL
665            }
666            Self::ProtocolCanisterManagement => {
667                NNS_PROPOSAL_TOPIC_PROTOCOL_CANISTER_MANAGEMENT_LABEL
668            }
669        }
670    }
671
672    #[cfg(feature = "host")]
673    pub(in crate::nns) const fn topic_code(self) -> Option<i32> {
674        match self {
675            Self::Any => None,
676            Self::NeuronManagement => Some(NNS_PROPOSAL_TOPIC_NEURON_MANAGEMENT_CODE),
677            Self::ExchangeRate => Some(NNS_PROPOSAL_TOPIC_EXCHANGE_RATE_CODE),
678            Self::NetworkEconomics => Some(NNS_PROPOSAL_TOPIC_NETWORK_ECONOMICS_CODE),
679            Self::Governance => Some(NNS_PROPOSAL_TOPIC_GOVERNANCE_CODE),
680            Self::NodeAdmin => Some(NNS_PROPOSAL_TOPIC_NODE_ADMIN_CODE),
681            Self::ParticipantManagement => Some(NNS_PROPOSAL_TOPIC_PARTICIPANT_MANAGEMENT_CODE),
682            Self::SubnetManagement => Some(NNS_PROPOSAL_TOPIC_SUBNET_MANAGEMENT_CODE),
683            Self::NetworkCanisterManagement => {
684                Some(NNS_PROPOSAL_TOPIC_NETWORK_CANISTER_MANAGEMENT_CODE)
685            }
686            Self::Kyc => Some(NNS_PROPOSAL_TOPIC_KYC_CODE),
687            Self::NodeProviderRewards => Some(NNS_PROPOSAL_TOPIC_NODE_PROVIDER_REWARDS_CODE),
688            Self::IcOsVersionDeployment => Some(NNS_PROPOSAL_TOPIC_IC_OS_VERSION_DEPLOYMENT_CODE),
689            Self::IcOsVersionElection => Some(NNS_PROPOSAL_TOPIC_IC_OS_VERSION_ELECTION_CODE),
690            Self::SnsAndCommunityFund => Some(NNS_PROPOSAL_TOPIC_SNS_AND_COMMUNITY_FUND_CODE),
691            Self::ApiBoundaryNodeManagement => {
692                Some(NNS_PROPOSAL_TOPIC_API_BOUNDARY_NODE_MANAGEMENT_CODE)
693            }
694            Self::SubnetRental => Some(NNS_PROPOSAL_TOPIC_SUBNET_RENTAL_CODE),
695            Self::ApplicationCanisterManagement => {
696                Some(NNS_PROPOSAL_TOPIC_APPLICATION_CANISTER_MANAGEMENT_CODE)
697            }
698            Self::ProtocolCanisterManagement => {
699                Some(NNS_PROPOSAL_TOPIC_PROTOCOL_CANISTER_MANAGEMENT_CODE)
700            }
701        }
702    }
703}