use crate::report::SortDirection;
use serde::{Deserialize, Serialize};
macro_rules! governance_code_enum {
(
$(#[$enum_attr:meta])*
pub enum $name:ident {
$(#[$unspecified_attr:meta])* Unspecified = 0 => "unspecified",
$($(#[$variant_attr:meta])* $variant:ident = $code:literal => $label:literal,)*
}
filter $filter:ident;
) => {
$(#[$enum_attr])*
pub enum $name {
$(#[$unspecified_attr])* #[serde(rename = "unspecified")] Unspecified,
$($(#[$variant_attr])* #[serde(rename = $label)] $variant,)*
}
impl $name {
#[must_use]
pub const fn from_code(code: i32) -> Self {
match code {
$($code => Self::$variant,)*
_ => Self::Unspecified,
}
}
#[must_use]
pub const fn code(self) -> i32 {
match self { Self::Unspecified => 0, $(Self::$variant => $code,)* }
}
#[must_use]
pub const fn as_str(self) -> &'static str {
match self { Self::Unspecified => "unspecified", $(Self::$variant => $label,)* }
}
}
#[doc = stringify!($filter)]
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
pub enum $filter {
#[default]
Any,
$($(#[$variant_attr])* $variant,)*
}
impl $filter {
pub const ALL: &'static [Self] = &[Self::Any, $(Self::$variant,)*];
#[must_use]
pub const fn as_str(self) -> &'static str {
match self.classification() { None => "any", Some(value) => value.as_str() }
}
const fn classification(self) -> Option<$name> {
match self { Self::Any => None, $(Self::$variant => Some($name::$variant),)* }
}
}
};
}
governance_code_enum! {
#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
pub enum NnsProposalStatus {
Unspecified = 0 => "unspecified",
Open = 1 => "open",
Rejected = 2 => "rejected",
Adopted = 3 => "adopted",
Executed = 4 => "executed",
Failed = 5 => "failed",
}
filter NnsProposalStatusFilter;
}
governance_code_enum! {
#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
pub enum NnsProposalRewardStatus {
Unspecified = 0 => "unspecified",
AcceptVotes = 1 => "accept-votes",
ReadyToSettle = 2 => "ready-to-settle",
Settled = 3 => "settled",
Ineligible = 4 => "ineligible",
}
filter NnsProposalRewardStatusFilter;
}
governance_code_enum! {
#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
pub enum NnsProposalTopic {
Unspecified = 0 => "unspecified",
NeuronManagement = 1 => "neuron-management",
ExchangeRate = 2 => "exchange-rate",
NetworkEconomics = 3 => "network-economics",
Governance = 4 => "governance",
NodeAdmin = 5 => "node-admin",
ParticipantManagement = 6 => "participant-management",
SubnetManagement = 7 => "subnet-management",
NetworkCanisterManagement = 8 => "network-canister-management",
Kyc = 9 => "kyc",
NodeProviderRewards = 10 => "node-provider-rewards",
IcOsVersionDeployment = 12 => "ic-os-version-deployment",
IcOsVersionElection = 13 => "ic-os-version-election",
SnsAndCommunityFund = 14 => "sns-and-community-fund",
ApiBoundaryNodeManagement = 15 => "api-boundary-node-management",
SubnetRental = 16 => "subnet-rental",
ApplicationCanisterManagement = 17 => "application-canister-management",
ProtocolCanisterManagement = 18 => "protocol-canister-management",
}
filter NnsProposalTopicFilter;
}
macro_rules! proposal_sort {
($($(#[$attr:meta])* $variant:ident => $label:literal,)*) => {
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
pub enum NnsProposalListSort { $($(#[$attr])* $variant,)* }
impl NnsProposalListSort {
pub const ALL: &'static [Self] = &[$(Self::$variant,)*];
#[must_use]
pub const fn as_str(self) -> &'static str {
match self { $(Self::$variant => $label,)* }
}
}
};
}
proposal_sort! {
#[default]
Api => "api",
Id => "id",
Status => "status",
RewardStatus => "reward-status",
Topic => "topic",
Proposer => "proposer",
Title => "title",
Action => "action",
Yes => "yes",
No => "no",
TotalVotes => "total-votes",
TallyTime => "tally-time",
VotingPower => "voting-power",
Ballots => "ballots",
RejectCost => "reject-cost",
RewardRound => "reward-round",
Proposed => "proposed",
Deadline => "deadline",
Decided => "decided",
Executed => "executed",
Failed => "failed",
}
impl NnsProposalListSort {
#[must_use]
pub const fn default_direction(self) -> SortDirection {
match self {
Self::Status
| Self::RewardStatus
| Self::Topic
| Self::Proposer
| Self::Title
| Self::Action => SortDirection::Asc,
_ => SortDirection::Desc,
}
}
#[must_use]
pub const fn uses_local_direction(self) -> bool {
!matches!(self, Self::Api)
}
#[must_use]
pub const fn direction_label(self, direction: SortDirection) -> &'static str {
match self {
Self::Api => "none",
_ => direction.as_str(),
}
}
}
impl NnsProposalStatusFilter {
#[cfg(any(
feature = "nns-host",
all(feature = "canister", target_arch = "wasm32")
))]
pub(in crate::nns) const fn governance_status_code(self) -> Option<i32> {
match self.classification() {
None => None,
Some(value) => Some(value.code()),
}
}
}
impl NnsProposalRewardStatusFilter {
#[cfg(any(
feature = "nns-host",
all(feature = "canister", target_arch = "wasm32")
))]
pub(in crate::nns) const fn governance_reward_status_code(self) -> Option<i32> {
match self.classification() {
None => None,
Some(value) => Some(value.code()),
}
}
}
impl NnsProposalTopicFilter {
pub(in crate::nns) const fn topic_code(self) -> Option<i32> {
match self.classification() {
None => None,
Some(value) => Some(value.code()),
}
}
}
#[cfg(test)]
mod tests;