1use anchor_lang::prelude::*;
2
3#[derive(Debug, thiserror::Error)]
5pub enum ActionError {
6 #[error("preconditions are not met: {0}")]
8 PreconditionsAreNotMet(&'static str),
9}
10
11type ActionResult<T> = std::result::Result<T, ActionError>;
12
13pub const MAX_ACTION_FLAGS: usize = 8;
15
16#[repr(u8)]
18#[non_exhaustive]
19#[derive(num_enum::IntoPrimitive, num_enum::TryFromPrimitive)]
20pub enum ActionFlag {
21 ShouldUnwrapNativeToken,
23 }
25
26#[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,
49 Completed,
51 Cancelled,
53}
54
55impl ActionState {
56 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 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 pub fn is_completed_or_cancelled(&self) -> bool {
74 matches!(self, Self::Completed | Self::Cancelled)
75 }
76
77 pub fn is_pending(&self) -> bool {
79 matches!(self, Self::Pending)
80 }
81
82 pub fn is_cancelled(&self) -> bool {
84 matches!(self, Self::Cancelled)
85 }
86
87 pub fn is_completed(&self) -> bool {
89 matches!(self, Self::Completed)
90 }
91}