gpl_feature_proposal/
state.rs1use borsh::{BorshDeserialize, BorshSchema, BorshSerialize};
3use gemachain_program::{
4 clock::UnixTimestamp,
5 msg,
6 program_error::ProgramError,
7 program_pack::{Pack, Sealed},
8};
9
10#[derive(Clone, Debug, BorshSerialize, BorshDeserialize, BorshSchema, PartialEq)]
12pub struct AcceptanceCriteria {
13 pub tokens_required: u64,
16
17 pub deadline: UnixTimestamp,
19}
20
21#[derive(Clone, Debug, BorshSerialize, BorshDeserialize, BorshSchema, PartialEq)]
23pub enum FeatureProposal {
24 Uninitialized,
26 Pending(AcceptanceCriteria),
28 Accepted {
30 #[allow(dead_code)] tokens_upon_acceptance: u64,
33 },
34 Expired,
36}
37impl Sealed for FeatureProposal {}
38
39impl Pack for FeatureProposal {
40 const LEN: usize = 17; fn pack_into_slice(&self, dst: &mut [u8]) {
43 let data = self.try_to_vec().unwrap();
44 dst[..data.len()].copy_from_slice(&data);
45 }
46
47 fn unpack_from_slice(src: &[u8]) -> Result<Self, ProgramError> {
48 let mut mut_src: &[u8] = src;
49 Self::deserialize(&mut mut_src).map_err(|err| {
50 msg!(
51 "Error: failed to deserialize feature proposal account: {}",
52 err
53 );
54 ProgramError::InvalidAccountData
55 })
56 }
57}
58
59#[cfg(test)]
60mod tests {
61 use super::*;
62
63 #[test]
64 fn test_get_packed_len() {
65 assert_eq!(
66 FeatureProposal::get_packed_len(),
67 gemachain_program::borsh::get_packed_len::<FeatureProposal>()
68 );
69 }
70
71 #[test]
72 fn test_serialize_bytes() {
73 assert_eq!(FeatureProposal::Expired.try_to_vec().unwrap(), vec![3]);
74
75 assert_eq!(
76 FeatureProposal::Pending(AcceptanceCriteria {
77 tokens_required: 0xdeadbeefdeadbeef,
78 deadline: -1,
79 })
80 .try_to_vec()
81 .unwrap(),
82 vec![1, 239, 190, 173, 222, 239, 190, 173, 222, 255, 255, 255, 255, 255, 255, 255, 255],
83 );
84 }
85
86 #[test]
87 fn test_serialize_large_slice() {
88 let mut dst = vec![0xff; 4];
89 FeatureProposal::Expired.pack_into_slice(&mut dst);
90
91 assert_eq!(dst, vec![3, 0xff, 0xff, 0xff]);
93 }
94
95 #[test]
96 fn state_deserialize_invalid() {
97 assert_eq!(
98 FeatureProposal::unpack_from_slice(&[3]),
99 Ok(FeatureProposal::Expired),
100 );
101
102 assert_eq!(
104 FeatureProposal::unpack_from_slice(&[3, 0xff, 0xff, 0xff]),
105 Ok(FeatureProposal::Expired),
106 );
107
108 assert_eq!(
109 FeatureProposal::unpack_from_slice(&[4]),
110 Err(ProgramError::InvalidAccountData),
111 );
112 }
113}