Skip to main content

miraland_program/stake/
stake_flags.rs

1use borsh::{BorshDeserialize, BorshSchema, BorshSerialize};
2
3/// Additional flags for stake state.
4#[derive(
5    Serialize,
6    Deserialize,
7    AbiExample,
8    BorshDeserialize,
9    BorshSchema,
10    BorshSerialize,
11    Copy,
12    PartialEq,
13    Eq,
14    Clone,
15    PartialOrd,
16    Ord,
17    Hash,
18    Debug,
19)]
20#[borsh(crate = "borsh")]
21pub struct StakeFlags {
22    bits: u8,
23}
24impl borsh0_10::de::BorshDeserialize for StakeFlags {
25    fn deserialize_reader<R: borsh0_10::maybestd::io::Read>(
26        reader: &mut R,
27    ) -> ::core::result::Result<Self, borsh0_10::maybestd::io::Error> {
28        Ok(Self {
29            bits: borsh0_10::BorshDeserialize::deserialize_reader(reader)?,
30        })
31    }
32}
33impl borsh0_10::BorshSchema for StakeFlags {
34    fn declaration() -> borsh0_10::schema::Declaration {
35        "StakeFlags".to_string()
36    }
37    fn add_definitions_recursively(
38        definitions: &mut borsh0_10::maybestd::collections::HashMap<
39            borsh0_10::schema::Declaration,
40            borsh0_10::schema::Definition,
41        >,
42    ) {
43        let fields = borsh0_10::schema::Fields::NamedFields(<[_]>::into_vec(
44            borsh0_10::maybestd::boxed::Box::new([(
45                "bits".to_string(),
46                <u8 as borsh0_10::BorshSchema>::declaration(),
47            )]),
48        ));
49        let definition = borsh0_10::schema::Definition::Struct { fields };
50        Self::add_definition(
51            <Self as borsh0_10::BorshSchema>::declaration(),
52            definition,
53            definitions,
54        );
55        <u8 as borsh0_10::BorshSchema>::add_definitions_recursively(definitions);
56    }
57}
58impl borsh0_10::ser::BorshSerialize for StakeFlags {
59    fn serialize<W: borsh0_10::maybestd::io::Write>(
60        &self,
61        writer: &mut W,
62    ) -> ::core::result::Result<(), borsh0_10::maybestd::io::Error> {
63        borsh0_10::BorshSerialize::serialize(&self.bits, writer)?;
64        Ok(())
65    }
66}
67
68/// Currently, only bit 1 is used. The other 7 bits are reserved for future usage.
69impl StakeFlags {
70    ///  Stake must be fully activated before deactivation is allowed (bit 1).
71    pub const MUST_FULLY_ACTIVATE_BEFORE_DEACTIVATION_IS_PERMITTED: Self =
72        Self { bits: 0b0000_0001 };
73
74    pub const fn empty() -> Self {
75        Self { bits: 0 }
76    }
77
78    pub const fn contains(&self, other: Self) -> bool {
79        (self.bits & other.bits) == other.bits
80    }
81
82    pub fn remove(&mut self, other: Self) {
83        self.bits &= !other.bits;
84    }
85
86    pub fn set(&mut self, other: Self) {
87        self.bits |= other.bits;
88    }
89
90    pub const fn union(self, other: Self) -> Self {
91        Self {
92            bits: self.bits | other.bits,
93        }
94    }
95}
96
97impl Default for StakeFlags {
98    fn default() -> Self {
99        StakeFlags::empty()
100    }
101}
102
103#[cfg(test)]
104mod test {
105    use super::*;
106
107    #[test]
108    fn test_stake_flags() {
109        let mut f = StakeFlags::empty();
110        assert!(!f.contains(StakeFlags::MUST_FULLY_ACTIVATE_BEFORE_DEACTIVATION_IS_PERMITTED));
111
112        f.set(StakeFlags::MUST_FULLY_ACTIVATE_BEFORE_DEACTIVATION_IS_PERMITTED);
113        assert!(f.contains(StakeFlags::MUST_FULLY_ACTIVATE_BEFORE_DEACTIVATION_IS_PERMITTED));
114
115        f.remove(StakeFlags::MUST_FULLY_ACTIVATE_BEFORE_DEACTIVATION_IS_PERMITTED);
116        assert!(!f.contains(StakeFlags::MUST_FULLY_ACTIVATE_BEFORE_DEACTIVATION_IS_PERMITTED));
117
118        let f1 = StakeFlags::empty();
119        let f2 = StakeFlags::empty();
120        let f3 = f1.union(f2);
121        assert!(!f3.contains(StakeFlags::MUST_FULLY_ACTIVATE_BEFORE_DEACTIVATION_IS_PERMITTED));
122
123        let f1 = StakeFlags::MUST_FULLY_ACTIVATE_BEFORE_DEACTIVATION_IS_PERMITTED;
124        let f2 = StakeFlags::empty();
125        let f3 = f1.union(f2);
126        assert!(f3.contains(StakeFlags::MUST_FULLY_ACTIVATE_BEFORE_DEACTIVATION_IS_PERMITTED));
127
128        let f1 = StakeFlags::empty();
129        let f2 = StakeFlags::MUST_FULLY_ACTIVATE_BEFORE_DEACTIVATION_IS_PERMITTED;
130        let f3 = f1.union(f2);
131        assert!(f3.contains(StakeFlags::MUST_FULLY_ACTIVATE_BEFORE_DEACTIVATION_IS_PERMITTED));
132
133        let f1 = StakeFlags::MUST_FULLY_ACTIVATE_BEFORE_DEACTIVATION_IS_PERMITTED;
134        let f2 = StakeFlags::MUST_FULLY_ACTIVATE_BEFORE_DEACTIVATION_IS_PERMITTED;
135        let f3 = f1.union(f2);
136        assert!(f3.contains(StakeFlags::MUST_FULLY_ACTIVATE_BEFORE_DEACTIVATION_IS_PERMITTED));
137    }
138}