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