Skip to main content

ic_query/sns/report/model/sorts/
proposals.rs

1//! Module: sns::report::model::sorts::proposals
2//!
3//! Responsibility: SNS proposal report sort and filter models.
4//! Does not own: CLI parsing, live proposal request transport, or rendering.
5//! Boundary: names report-level view options for proposal lists.
6
7use crate::report::SortDirection;
8
9pub(in crate::sns::report) const SNS_PROPOSAL_STATUS_ADOPTED_CODE: i32 = 3;
10pub(in crate::sns::report) const SNS_PROPOSAL_STATUS_EXECUTED_CODE: i32 = 4;
11pub(in crate::sns::report) const SNS_PROPOSAL_STATUS_FAILED_CODE: i32 = 5;
12pub(in crate::sns::report) const SNS_PROPOSAL_STATUS_OPEN_CODE: i32 = 1;
13pub(in crate::sns::report) const SNS_PROPOSAL_STATUS_REJECTED_CODE: i32 = 2;
14
15///
16/// SnsProposalsSort
17///
18/// Report-model sort selector for SNS proposal listings.
19///
20
21#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
22pub enum SnsProposalsSort {
23    #[default]
24    Api,
25    Id,
26    Status,
27    Topic,
28    Proposer,
29    Title,
30    Action,
31    ActionId,
32    Yes,
33    No,
34    TotalVotes,
35    TallyTime,
36    Ballots,
37    Eligible,
38    RejectCost,
39    RewardRound,
40    RewardEnd,
41    Created,
42    Decided,
43    Executed,
44    Failed,
45}
46
47impl SnsProposalsSort {
48    /// Return the stable label used in text and JSON reports.
49    #[must_use]
50    pub const fn as_str(self) -> &'static str {
51        match self {
52            Self::Api => "api",
53            Self::Id => "id",
54            Self::Status => "status",
55            Self::Topic => "topic",
56            Self::Proposer => "proposer",
57            Self::Title => "title",
58            Self::Action => "action",
59            Self::ActionId => "action-id",
60            Self::Yes => "yes",
61            Self::No => "no",
62            Self::TotalVotes => "total-votes",
63            Self::TallyTime => "tally-time",
64            Self::Ballots => "ballots",
65            Self::Eligible => "eligible",
66            Self::RejectCost => "reject-cost",
67            Self::RewardRound => "reward-round",
68            Self::RewardEnd => "reward-end",
69            Self::Created => "created",
70            Self::Decided => "decided",
71            Self::Executed => "executed",
72            Self::Failed => "failed",
73        }
74    }
75
76    /// Return the natural default direction for this local sort value.
77    #[must_use]
78    pub const fn default_direction(self) -> SortDirection {
79        match self {
80            Self::Status | Self::Topic | Self::Proposer | Self::Title | Self::Action => {
81                SortDirection::Asc
82            }
83            _ => SortDirection::Desc,
84        }
85    }
86
87    /// Return whether this sort applies a local direction.
88    #[must_use]
89    pub const fn uses_local_direction(self) -> bool {
90        !matches!(self, Self::Api)
91    }
92
93    /// Return the stable direction label used in text and JSON reports.
94    #[must_use]
95    pub const fn direction_label(self, direction: SortDirection) -> &'static str {
96        match self {
97            Self::Api => "none",
98            _ => direction.as_str(),
99        }
100    }
101}
102
103///
104/// SnsProposalEligibilityFilter
105///
106/// Report-model reward eligibility filter for SNS proposal listings.
107///
108
109#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
110pub enum SnsProposalEligibilityFilter {
111    #[default]
112    Any,
113    Yes,
114    No,
115}
116
117impl SnsProposalEligibilityFilter {
118    /// Return the stable label used in text and JSON reports.
119    #[must_use]
120    pub const fn as_str(self) -> &'static str {
121        match self {
122            Self::Any => "any",
123            Self::Yes => "yes",
124            Self::No => "no",
125        }
126    }
127
128    /// Return the boolean row value for concrete eligibility filters.
129    #[must_use]
130    pub const fn eligibility_value(self) -> Option<bool> {
131        match self {
132            Self::Any => None,
133            Self::Yes => Some(true),
134            Self::No => Some(false),
135        }
136    }
137}
138
139///
140/// SnsProposalStatusFilter
141///
142/// Report-model status filter for bounded SNS proposal listings.
143///
144
145#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
146pub enum SnsProposalStatusFilter {
147    #[default]
148    Any,
149    Open,
150    Decided,
151    Rejected,
152    Adopted,
153    Executed,
154    Failed,
155}
156
157impl SnsProposalStatusFilter {
158    /// Return the stable label used in text and JSON reports.
159    #[must_use]
160    pub const fn as_str(self) -> &'static str {
161        match self {
162            Self::Any => "any",
163            Self::Open => "open",
164            Self::Decided => "decided",
165            Self::Rejected => "rejected",
166            Self::Adopted => "adopted",
167            Self::Executed => "executed",
168            Self::Failed => "failed",
169        }
170    }
171
172    /// Return the SNS governance API status code for concrete filters.
173    #[must_use]
174    pub const fn governance_status_code(self) -> Option<i32> {
175        match self {
176            Self::Any | Self::Decided => None,
177            Self::Open => Some(SNS_PROPOSAL_STATUS_OPEN_CODE),
178            Self::Rejected => Some(SNS_PROPOSAL_STATUS_REJECTED_CODE),
179            Self::Adopted => Some(SNS_PROPOSAL_STATUS_ADOPTED_CODE),
180            Self::Executed => Some(SNS_PROPOSAL_STATUS_EXECUTED_CODE),
181            Self::Failed => Some(SNS_PROPOSAL_STATUS_FAILED_CODE),
182        }
183    }
184}
185
186///
187/// SnsProposalTopicFilter
188///
189/// Report-model topic filter for bounded SNS proposal listings.
190///
191
192#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
193pub enum SnsProposalTopicFilter {
194    #[default]
195    Any,
196    DaoCommunitySettings,
197    SnsFrameworkManagement,
198    DappCanisterManagement,
199    ApplicationBusinessLogic,
200    Governance,
201    TreasuryAssetManagement,
202    CriticalDappOperations,
203}
204
205impl SnsProposalTopicFilter {
206    /// Return the stable label used in text and JSON reports.
207    #[must_use]
208    pub const fn as_str(self) -> &'static str {
209        match self {
210            Self::Any => "any",
211            Self::DaoCommunitySettings => "dao-community-settings",
212            Self::SnsFrameworkManagement => "sns-framework-management",
213            Self::DappCanisterManagement => "dapp-canister-management",
214            Self::ApplicationBusinessLogic => "application-business-logic",
215            Self::Governance => "governance",
216            Self::TreasuryAssetManagement => "treasury-asset-management",
217            Self::CriticalDappOperations => "critical-dapp-operations",
218        }
219    }
220
221    /// Return the row topic label for concrete topic filters.
222    #[must_use]
223    pub const fn topic_label(self) -> Option<&'static str> {
224        match self {
225            Self::Any => None,
226            _ => Some(self.as_str()),
227        }
228    }
229}