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    /// All supported choices in their public presentation order.
49    pub const ALL: &'static [Self] = &[
50        Self::Api,
51        Self::Id,
52        Self::Status,
53        Self::Topic,
54        Self::Proposer,
55        Self::Title,
56        Self::Action,
57        Self::ActionId,
58        Self::Yes,
59        Self::No,
60        Self::TotalVotes,
61        Self::TallyTime,
62        Self::Ballots,
63        Self::Eligible,
64        Self::RejectCost,
65        Self::RewardRound,
66        Self::RewardEnd,
67        Self::Created,
68        Self::Decided,
69        Self::Executed,
70        Self::Failed,
71    ];
72
73    /// Return the stable label used in text and JSON reports.
74    #[must_use]
75    pub const fn as_str(self) -> &'static str {
76        match self {
77            Self::Api => "api",
78            Self::Id => "id",
79            Self::Status => "status",
80            Self::Topic => "topic",
81            Self::Proposer => "proposer",
82            Self::Title => "title",
83            Self::Action => "action",
84            Self::ActionId => "action-id",
85            Self::Yes => "yes",
86            Self::No => "no",
87            Self::TotalVotes => "total-votes",
88            Self::TallyTime => "tally-time",
89            Self::Ballots => "ballots",
90            Self::Eligible => "eligible",
91            Self::RejectCost => "reject-cost",
92            Self::RewardRound => "reward-round",
93            Self::RewardEnd => "reward-end",
94            Self::Created => "created",
95            Self::Decided => "decided",
96            Self::Executed => "executed",
97            Self::Failed => "failed",
98        }
99    }
100
101    /// Return the natural default direction for this local sort value.
102    #[must_use]
103    pub const fn default_direction(self) -> SortDirection {
104        match self {
105            Self::Status | Self::Topic | Self::Proposer | Self::Title | Self::Action => {
106                SortDirection::Asc
107            }
108            _ => SortDirection::Desc,
109        }
110    }
111
112    /// Return whether this sort applies a local direction.
113    #[must_use]
114    pub const fn uses_local_direction(self) -> bool {
115        !matches!(self, Self::Api)
116    }
117
118    /// Return the stable direction label used in text and JSON reports.
119    #[must_use]
120    pub const fn direction_label(self, direction: SortDirection) -> &'static str {
121        match self {
122            Self::Api => "none",
123            _ => direction.as_str(),
124        }
125    }
126}
127
128///
129/// SnsProposalEligibilityFilter
130///
131/// Report-model reward eligibility filter for SNS proposal listings.
132///
133
134#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
135pub enum SnsProposalEligibilityFilter {
136    #[default]
137    Any,
138    Yes,
139    No,
140}
141
142impl SnsProposalEligibilityFilter {
143    /// All supported choices in their public presentation order.
144    pub const ALL: &'static [Self] = &[Self::Any, Self::Yes, Self::No];
145
146    /// Return the stable label used in text and JSON reports.
147    #[must_use]
148    pub const fn as_str(self) -> &'static str {
149        match self {
150            Self::Any => "any",
151            Self::Yes => "yes",
152            Self::No => "no",
153        }
154    }
155
156    /// Return the boolean row value for concrete eligibility filters.
157    #[must_use]
158    pub const fn eligibility_value(self) -> Option<bool> {
159        match self {
160            Self::Any => None,
161            Self::Yes => Some(true),
162            Self::No => Some(false),
163        }
164    }
165}
166
167///
168/// SnsProposalStatusFilter
169///
170/// Report-model status filter for bounded SNS proposal listings.
171///
172
173#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
174pub enum SnsProposalStatusFilter {
175    #[default]
176    Any,
177    Open,
178    Decided,
179    Rejected,
180    Adopted,
181    Executed,
182    Failed,
183}
184
185impl SnsProposalStatusFilter {
186    /// All supported choices in their public presentation order.
187    pub const ALL: &'static [Self] = &[
188        Self::Any,
189        Self::Open,
190        Self::Decided,
191        Self::Rejected,
192        Self::Adopted,
193        Self::Executed,
194        Self::Failed,
195    ];
196
197    /// Return the stable label used in text and JSON reports.
198    #[must_use]
199    pub const fn as_str(self) -> &'static str {
200        match self {
201            Self::Any => "any",
202            Self::Open => "open",
203            Self::Decided => "decided",
204            Self::Rejected => "rejected",
205            Self::Adopted => "adopted",
206            Self::Executed => "executed",
207            Self::Failed => "failed",
208        }
209    }
210
211    /// Return the SNS governance API status code for concrete filters.
212    #[must_use]
213    pub const fn governance_status_code(self) -> Option<i32> {
214        match self {
215            Self::Any | Self::Decided => None,
216            Self::Open => Some(SNS_PROPOSAL_STATUS_OPEN_CODE),
217            Self::Rejected => Some(SNS_PROPOSAL_STATUS_REJECTED_CODE),
218            Self::Adopted => Some(SNS_PROPOSAL_STATUS_ADOPTED_CODE),
219            Self::Executed => Some(SNS_PROPOSAL_STATUS_EXECUTED_CODE),
220            Self::Failed => Some(SNS_PROPOSAL_STATUS_FAILED_CODE),
221        }
222    }
223}
224
225///
226/// SnsProposalTopicFilter
227///
228/// Report-model topic filter for bounded SNS proposal listings.
229///
230
231#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
232pub enum SnsProposalTopicFilter {
233    #[default]
234    Any,
235    DaoCommunitySettings,
236    SnsFrameworkManagement,
237    DappCanisterManagement,
238    ApplicationBusinessLogic,
239    Governance,
240    TreasuryAssetManagement,
241    CriticalDappOperations,
242}
243
244impl SnsProposalTopicFilter {
245    /// All supported choices in their public presentation order.
246    pub const ALL: &'static [Self] = &[
247        Self::Any,
248        Self::DaoCommunitySettings,
249        Self::SnsFrameworkManagement,
250        Self::DappCanisterManagement,
251        Self::ApplicationBusinessLogic,
252        Self::Governance,
253        Self::TreasuryAssetManagement,
254        Self::CriticalDappOperations,
255    ];
256
257    /// Return the stable label used in text and JSON reports.
258    #[must_use]
259    pub const fn as_str(self) -> &'static str {
260        match self {
261            Self::Any => "any",
262            Self::DaoCommunitySettings => "dao-community-settings",
263            Self::SnsFrameworkManagement => "sns-framework-management",
264            Self::DappCanisterManagement => "dapp-canister-management",
265            Self::ApplicationBusinessLogic => "application-business-logic",
266            Self::Governance => "governance",
267            Self::TreasuryAssetManagement => "treasury-asset-management",
268            Self::CriticalDappOperations => "critical-dapp-operations",
269        }
270    }
271
272    /// Return the row topic label for concrete topic filters.
273    #[must_use]
274    pub const fn topic_label(self) -> Option<&'static str> {
275        match self {
276            Self::Any => None,
277            _ => Some(self.as_str()),
278        }
279    }
280}