gmsol_utils/
action.rs

1use anchor_lang::prelude::*;
2
3/// Action error.
4#[derive(Debug, thiserror::Error)]
5pub enum ActionError {
6    /// Preconditions are not met.
7    #[error("preconditions are not met: {0}")]
8    PreconditionsAreNotMet(&'static str),
9}
10
11type ActionResult<T> = std::result::Result<T, ActionError>;
12
13/// Max number of aciton flags.
14pub const MAX_ACTION_FLAGS: usize = 8;
15
16/// Action Flags.
17#[repr(u8)]
18#[non_exhaustive]
19#[derive(num_enum::IntoPrimitive, num_enum::TryFromPrimitive)]
20pub enum ActionFlag {
21    /// Should unwrap native token.
22    ShouldUnwrapNativeToken,
23    // CHECK: should have no more than `MAX_ACTION_FLAGS` of flags.
24}
25
26/// Action State.
27#[non_exhaustive]
28#[repr(u8)]
29#[derive(
30    Clone,
31    Copy,
32    num_enum::IntoPrimitive,
33    num_enum::TryFromPrimitive,
34    PartialEq,
35    Eq,
36    strum::EnumString,
37    strum::Display,
38    AnchorSerialize,
39    AnchorDeserialize,
40    InitSpace,
41)]
42#[strum(serialize_all = "snake_case")]
43#[cfg_attr(feature = "debug", derive(Debug))]
44#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
45#[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))]
46pub enum ActionState {
47    /// Pending.
48    Pending,
49    /// Completed.
50    Completed,
51    /// Cancelled.
52    Cancelled,
53}
54
55impl ActionState {
56    /// Transition to Completed State.
57    pub fn completed(self) -> ActionResult<Self> {
58        let Self::Pending = self else {
59            return Err(ActionError::PreconditionsAreNotMet("expected pending"));
60        };
61        Ok(Self::Completed)
62    }
63
64    /// Transition to Cancelled State.
65    pub fn cancelled(self) -> ActionResult<Self> {
66        let Self::Pending = self else {
67            return Err(ActionError::PreconditionsAreNotMet("expected pending"));
68        };
69        Ok(Self::Cancelled)
70    }
71
72    /// Check if the state is completed or cancelled.
73    pub fn is_completed_or_cancelled(&self) -> bool {
74        matches!(self, Self::Completed | Self::Cancelled)
75    }
76
77    /// Check if the state is pending.
78    pub fn is_pending(&self) -> bool {
79        matches!(self, Self::Pending)
80    }
81
82    /// Check if the state is cancelled.
83    pub fn is_cancelled(&self) -> bool {
84        matches!(self, Self::Cancelled)
85    }
86
87    /// Check if the state is completed.
88    pub fn is_completed(&self) -> bool {
89        matches!(self, Self::Completed)
90    }
91}