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
167///
168/// NnsProposalRequest
169///
170/// Request accepted by the NNS proposal detail report builder.
171///
172
173#[derive(Clone, Debug, Eq, PartialEq)]
174pub struct NnsProposalRequest {
175    pub network: String,
176    pub source_endpoint: String,
177    pub now_unix_secs: u64,
178    pub proposal_id: u64,
179    pub show_ballots: bool,
180    pub verbose: bool,
181}
182
183///
184/// NnsProposalListReport
185///
186/// Serializable report for a bounded NNS governance proposal listing.
187///
188
189#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
190pub struct NnsProposalListReport {
191    pub schema_version: u32,
192    pub network: String,
193    pub governance_canister_id: String,
194    pub fetched_at: String,
195    pub source_endpoint: String,
196    pub fetched_by: String,
197    pub data_source: String,
198    pub cache_path: Option<String>,
199    pub cache_complete: Option<bool>,
200    pub requested_limit: u32,
201    pub before_proposal_id: Option<u64>,
202    pub status_filter: String,
203    pub reward_status_filter: String,
204    pub topic_filter: String,
205    pub proposer_filter: Option<u64>,
206    pub query_filter: Option<String>,
207    pub sort: String,
208    pub sort_direction: String,
209    pub result_scope: String,
210    pub verbose: bool,
211    pub proposal_count: usize,
212    pub proposals: Vec<NnsProposalRow>,
213}
214
215///
216/// NnsProposalReport
217///
218/// Serializable report for one NNS governance proposal detail lookup.
219///
220
221#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
222pub struct NnsProposalReport {
223    pub schema_version: u32,
224    pub network: String,
225    pub governance_canister_id: String,
226    pub fetched_at: String,
227    pub source_endpoint: String,
228    pub fetched_by: String,
229    pub data_source: String,
230    pub cache_path: Option<String>,
231    pub cache_complete: Option<bool>,
232    pub proposal_id: u64,
233    pub show_ballots: bool,
234    pub verbose: bool,
235    pub proposal: NnsProposalRow,
236}
237
238///
239/// NnsProposalRow
240///
241/// Serializable row for one NNS governance proposal.
242///
243
244#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
245pub struct NnsProposalRow {
246    pub proposal_id: Option<u64>,
247    pub proposer_neuron_id: Option<u64>,
248    pub topic: i32,
249    pub topic_text: String,
250    pub status: i32,
251    pub status_text: String,
252    pub reward_status: i32,
253    pub reward_status_text: String,
254    pub title: Option<String>,
255    pub summary: String,
256    pub url: String,
257    pub action_text: Option<String>,
258    pub reject_cost_e8s: u64,
259    pub proposal_timestamp_seconds: u64,
260    pub proposed_at: String,
261    pub deadline_timestamp_seconds: Option<u64>,
262    pub deadline_at: Option<String>,
263    pub decided_timestamp_seconds: u64,
264    pub decided_at: Option<String>,
265    pub executed_timestamp_seconds: u64,
266    pub executed_at: Option<String>,
267    pub failed_timestamp_seconds: u64,
268    pub failed_at: Option<String>,
269    pub reward_event_round: u64,
270    pub total_potential_voting_power: Option<u64>,
271    pub latest_tally: Option<NnsProposalTally>,
272    pub ballot_count: usize,
273    pub ballots: Vec<NnsProposalBallotRow>,
274}
275
276///
277/// NnsProposalBallotRow
278///
279/// Serializable NNS proposal ballot row.
280///
281
282#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
283pub struct NnsProposalBallotRow {
284    pub neuron_id: u64,
285    pub vote: i32,
286    pub vote_text: String,
287    pub voting_power: u64,
288}
289
290///
291/// NnsProposalTally
292///
293/// Serializable NNS proposal vote tally.
294///
295
296#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
297pub struct NnsProposalTally {
298    pub timestamp_seconds: u64,
299    pub yes: u64,
300    pub no: u64,
301    pub total: u64,
302}
303
304///
305/// NnsProposalListSort
306///
307/// Report-model sort selector for NNS proposal listings.
308///
309
310#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
311pub enum NnsProposalListSort {
312    #[default]
313    Api,
314    Id,
315    Status,
316    RewardStatus,
317    Topic,
318    Proposer,
319    Title,
320    Action,
321    Yes,
322    No,
323    TotalVotes,
324    TallyTime,
325    VotingPower,
326    Ballots,
327    RejectCost,
328    RewardRound,
329    Proposed,
330    Deadline,
331    Decided,
332    Executed,
333    Failed,
334}
335
336impl NnsProposalListSort {
337    #[must_use]
338    pub const fn as_str(self) -> &'static str {
339        match self {
340            Self::Api => NNS_PROPOSAL_SORT_API_LABEL,
341            Self::Id => NNS_PROPOSAL_SORT_ID_LABEL,
342            Self::Status => NNS_PROPOSAL_SORT_STATUS_LABEL,
343            Self::RewardStatus => NNS_PROPOSAL_SORT_REWARD_STATUS_LABEL,
344            Self::Topic => NNS_PROPOSAL_SORT_TOPIC_LABEL,
345            Self::Proposer => NNS_PROPOSAL_SORT_PROPOSER_LABEL,
346            Self::Title => NNS_PROPOSAL_SORT_TITLE_LABEL,
347            Self::Action => NNS_PROPOSAL_SORT_ACTION_LABEL,
348            Self::Yes => NNS_PROPOSAL_SORT_YES_LABEL,
349            Self::No => NNS_PROPOSAL_SORT_NO_LABEL,
350            Self::TotalVotes => NNS_PROPOSAL_SORT_TOTAL_VOTES_LABEL,
351            Self::TallyTime => NNS_PROPOSAL_SORT_TALLY_TIME_LABEL,
352            Self::VotingPower => NNS_PROPOSAL_SORT_VOTING_POWER_LABEL,
353            Self::Ballots => NNS_PROPOSAL_SORT_BALLOTS_LABEL,
354            Self::RejectCost => NNS_PROPOSAL_SORT_REJECT_COST_LABEL,
355            Self::RewardRound => NNS_PROPOSAL_SORT_REWARD_ROUND_LABEL,
356            Self::Proposed => NNS_PROPOSAL_SORT_PROPOSED_LABEL,
357            Self::Deadline => NNS_PROPOSAL_SORT_DEADLINE_LABEL,
358            Self::Decided => NNS_PROPOSAL_SORT_DECIDED_LABEL,
359            Self::Executed => NNS_PROPOSAL_SORT_EXECUTED_LABEL,
360            Self::Failed => NNS_PROPOSAL_SORT_FAILED_LABEL,
361        }
362    }
363
364    #[must_use]
365    pub const fn default_direction(self) -> NnsProposalSortDirection {
366        match self {
367            Self::Status
368            | Self::RewardStatus
369            | Self::Topic
370            | Self::Proposer
371            | Self::Title
372            | Self::Action => NnsProposalSortDirection::Asc,
373            _ => NnsProposalSortDirection::Desc,
374        }
375    }
376
377    #[must_use]
378    pub const fn uses_local_direction(self) -> bool {
379        !matches!(self, Self::Api)
380    }
381
382    #[must_use]
383    pub const fn direction_label(self, direction: NnsProposalSortDirection) -> &'static str {
384        match self {
385            Self::Api => NNS_PROPOSAL_SORT_NONE_LABEL,
386            _ => direction.as_str(),
387        }
388    }
389}
390
391///
392/// NnsProposalSortDirection
393///
394/// Report-model direction selector for local NNS proposal sorting.
395///
396
397#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
398pub enum NnsProposalSortDirection {
399    Asc,
400    #[default]
401    Desc,
402}
403
404impl NnsProposalSortDirection {
405    #[must_use]
406    pub const fn as_str(self) -> &'static str {
407        match self {
408            Self::Asc => NNS_PROPOSAL_SORT_ASC_LABEL,
409            Self::Desc => NNS_PROPOSAL_SORT_DESC_LABEL,
410        }
411    }
412}
413
414///
415/// NnsProposalStatusFilter
416///
417/// Report-model status filter for bounded NNS proposal listings.
418///
419
420#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
421pub enum NnsProposalStatusFilter {
422    #[default]
423    Any,
424    Open,
425    Rejected,
426    Adopted,
427    Executed,
428    Failed,
429}
430
431///
432/// NnsProposalRewardStatusFilter
433///
434/// Report-model reward status filter for bounded NNS proposal listings.
435///
436
437#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
438pub enum NnsProposalRewardStatusFilter {
439    #[default]
440    Any,
441    AcceptVotes,
442    ReadyToSettle,
443    Settled,
444    Ineligible,
445}
446
447impl NnsProposalRewardStatusFilter {
448    #[must_use]
449    pub const fn as_str(self) -> &'static str {
450        match self {
451            Self::Any => NNS_PROPOSAL_REWARD_STATUS_ANY_LABEL,
452            Self::AcceptVotes => NNS_PROPOSAL_REWARD_STATUS_ACCEPT_VOTES_LABEL,
453            Self::ReadyToSettle => NNS_PROPOSAL_REWARD_STATUS_READY_TO_SETTLE_LABEL,
454            Self::Settled => NNS_PROPOSAL_REWARD_STATUS_SETTLED_LABEL,
455            Self::Ineligible => NNS_PROPOSAL_REWARD_STATUS_INELIGIBLE_LABEL,
456        }
457    }
458
459    #[cfg(feature = "host")]
460    pub(in crate::nns) const fn governance_reward_status_code(self) -> Option<i32> {
461        match self {
462            Self::Any => None,
463            Self::AcceptVotes => Some(NNS_PROPOSAL_REWARD_STATUS_ACCEPT_VOTES_CODE),
464            Self::ReadyToSettle => Some(NNS_PROPOSAL_REWARD_STATUS_READY_TO_SETTLE_CODE),
465            Self::Settled => Some(NNS_PROPOSAL_REWARD_STATUS_SETTLED_CODE),
466            Self::Ineligible => Some(NNS_PROPOSAL_REWARD_STATUS_INELIGIBLE_CODE),
467        }
468    }
469}
470
471impl NnsProposalStatusFilter {
472    #[must_use]
473    pub const fn as_str(self) -> &'static str {
474        match self {
475            Self::Any => NNS_PROPOSAL_STATUS_ANY_LABEL,
476            Self::Open => NNS_PROPOSAL_STATUS_OPEN_LABEL,
477            Self::Rejected => NNS_PROPOSAL_STATUS_REJECTED_LABEL,
478            Self::Adopted => NNS_PROPOSAL_STATUS_ADOPTED_LABEL,
479            Self::Executed => NNS_PROPOSAL_STATUS_EXECUTED_LABEL,
480            Self::Failed => NNS_PROPOSAL_STATUS_FAILED_LABEL,
481        }
482    }
483
484    #[cfg(feature = "host")]
485    pub(in crate::nns) const fn governance_status_code(self) -> Option<i32> {
486        match self {
487            Self::Any => None,
488            Self::Open => Some(NNS_PROPOSAL_STATUS_OPEN_CODE),
489            Self::Rejected => Some(NNS_PROPOSAL_STATUS_REJECTED_CODE),
490            Self::Adopted => Some(NNS_PROPOSAL_STATUS_ADOPTED_CODE),
491            Self::Executed => Some(NNS_PROPOSAL_STATUS_EXECUTED_CODE),
492            Self::Failed => Some(NNS_PROPOSAL_STATUS_FAILED_CODE),
493        }
494    }
495}
496
497///
498/// NnsProposalTopicFilter
499///
500/// Report-model topic filter for bounded NNS proposal listings.
501///
502
503#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
504pub enum NnsProposalTopicFilter {
505    #[default]
506    Any,
507    NeuronManagement,
508    ExchangeRate,
509    NetworkEconomics,
510    Governance,
511    NodeAdmin,
512    ParticipantManagement,
513    SubnetManagement,
514    NetworkCanisterManagement,
515    Kyc,
516    NodeProviderRewards,
517    IcOsVersionDeployment,
518    IcOsVersionElection,
519    SnsAndCommunityFund,
520    ApiBoundaryNodeManagement,
521    SubnetRental,
522    ApplicationCanisterManagement,
523    ProtocolCanisterManagement,
524}
525
526impl NnsProposalTopicFilter {
527    #[must_use]
528    pub const fn as_str(self) -> &'static str {
529        match self {
530            Self::Any => NNS_PROPOSAL_TOPIC_ANY_LABEL,
531            Self::NeuronManagement => NNS_PROPOSAL_TOPIC_NEURON_MANAGEMENT_LABEL,
532            Self::ExchangeRate => NNS_PROPOSAL_TOPIC_EXCHANGE_RATE_LABEL,
533            Self::NetworkEconomics => NNS_PROPOSAL_TOPIC_NETWORK_ECONOMICS_LABEL,
534            Self::Governance => NNS_PROPOSAL_TOPIC_GOVERNANCE_LABEL,
535            Self::NodeAdmin => NNS_PROPOSAL_TOPIC_NODE_ADMIN_LABEL,
536            Self::ParticipantManagement => NNS_PROPOSAL_TOPIC_PARTICIPANT_MANAGEMENT_LABEL,
537            Self::SubnetManagement => NNS_PROPOSAL_TOPIC_SUBNET_MANAGEMENT_LABEL,
538            Self::NetworkCanisterManagement => NNS_PROPOSAL_TOPIC_NETWORK_CANISTER_MANAGEMENT_LABEL,
539            Self::Kyc => NNS_PROPOSAL_TOPIC_KYC_LABEL,
540            Self::NodeProviderRewards => NNS_PROPOSAL_TOPIC_NODE_PROVIDER_REWARDS_LABEL,
541            Self::IcOsVersionDeployment => NNS_PROPOSAL_TOPIC_IC_OS_VERSION_DEPLOYMENT_LABEL,
542            Self::IcOsVersionElection => NNS_PROPOSAL_TOPIC_IC_OS_VERSION_ELECTION_LABEL,
543            Self::SnsAndCommunityFund => NNS_PROPOSAL_TOPIC_SNS_AND_COMMUNITY_FUND_LABEL,
544            Self::ApiBoundaryNodeManagement => {
545                NNS_PROPOSAL_TOPIC_API_BOUNDARY_NODE_MANAGEMENT_LABEL
546            }
547            Self::SubnetRental => NNS_PROPOSAL_TOPIC_SUBNET_RENTAL_LABEL,
548            Self::ApplicationCanisterManagement => {
549                NNS_PROPOSAL_TOPIC_APPLICATION_CANISTER_MANAGEMENT_LABEL
550            }
551            Self::ProtocolCanisterManagement => {
552                NNS_PROPOSAL_TOPIC_PROTOCOL_CANISTER_MANAGEMENT_LABEL
553            }
554        }
555    }
556
557    #[cfg(feature = "host")]
558    pub(in crate::nns) const fn topic_code(self) -> Option<i32> {
559        match self {
560            Self::Any => None,
561            Self::NeuronManagement => Some(NNS_PROPOSAL_TOPIC_NEURON_MANAGEMENT_CODE),
562            Self::ExchangeRate => Some(NNS_PROPOSAL_TOPIC_EXCHANGE_RATE_CODE),
563            Self::NetworkEconomics => Some(NNS_PROPOSAL_TOPIC_NETWORK_ECONOMICS_CODE),
564            Self::Governance => Some(NNS_PROPOSAL_TOPIC_GOVERNANCE_CODE),
565            Self::NodeAdmin => Some(NNS_PROPOSAL_TOPIC_NODE_ADMIN_CODE),
566            Self::ParticipantManagement => Some(NNS_PROPOSAL_TOPIC_PARTICIPANT_MANAGEMENT_CODE),
567            Self::SubnetManagement => Some(NNS_PROPOSAL_TOPIC_SUBNET_MANAGEMENT_CODE),
568            Self::NetworkCanisterManagement => {
569                Some(NNS_PROPOSAL_TOPIC_NETWORK_CANISTER_MANAGEMENT_CODE)
570            }
571            Self::Kyc => Some(NNS_PROPOSAL_TOPIC_KYC_CODE),
572            Self::NodeProviderRewards => Some(NNS_PROPOSAL_TOPIC_NODE_PROVIDER_REWARDS_CODE),
573            Self::IcOsVersionDeployment => Some(NNS_PROPOSAL_TOPIC_IC_OS_VERSION_DEPLOYMENT_CODE),
574            Self::IcOsVersionElection => Some(NNS_PROPOSAL_TOPIC_IC_OS_VERSION_ELECTION_CODE),
575            Self::SnsAndCommunityFund => Some(NNS_PROPOSAL_TOPIC_SNS_AND_COMMUNITY_FUND_CODE),
576            Self::ApiBoundaryNodeManagement => {
577                Some(NNS_PROPOSAL_TOPIC_API_BOUNDARY_NODE_MANAGEMENT_CODE)
578            }
579            Self::SubnetRental => Some(NNS_PROPOSAL_TOPIC_SUBNET_RENTAL_CODE),
580            Self::ApplicationCanisterManagement => {
581                Some(NNS_PROPOSAL_TOPIC_APPLICATION_CANISTER_MANAGEMENT_CODE)
582            }
583            Self::ProtocolCanisterManagement => {
584                Some(NNS_PROPOSAL_TOPIC_PROTOCOL_CANISTER_MANAGEMENT_CODE)
585            }
586        }
587    }
588}