module_ntoken/states/
nft.rs1use crate::constants::{
2 account_size::NFT_ACCOUNT_SIZE, constant::PUBKEY_SIZE, account_type::TYPE_ACCOUNT_NFT_ACCOUNT,
3};
4use anchor_lang::prelude::{ProgramError, Pubkey};
5use arrayref::{array_mut_ref, array_ref, array_refs, mut_array_refs};
6use serde::{Deserialize, Serialize};
7use solana_program::program_pack::{IsInitialized, Pack, Sealed};
8
9const TYPE_SIZE: usize = 1;
10const STAKE_SIZE: usize = 1;
11const NONCE_SIZE: usize = 1;
12
13#[repr(C)]
15#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
16pub struct NFTAccount {
17 pub type_account: u8,
19 pub owner: Pubkey,
21 pub stake: u8,
23 pub authority: Pubkey,
25 pub nonce: u8,
27 pub create_account_programm: Pubkey,
29}
30
31impl Sealed for NFTAccount {}
32
33impl IsInitialized for NFTAccount {
34 fn is_initialized(&self) -> bool {
35 return self.type_account == TYPE_ACCOUNT_NFT_ACCOUNT;
36 }
37}
38
39impl Pack for NFTAccount {
41 const LEN: usize = NFT_ACCOUNT_SIZE;
42 fn unpack_from_slice(src: &[u8]) -> Result<Self, ProgramError> {
44 let src = array_ref![src, 0, NFT_ACCOUNT_SIZE];
45 let (type_account, owner, stake, authority, nonce, create_account_programm) = array_refs![
46 src,
47 TYPE_SIZE,
48 PUBKEY_SIZE,
49 STAKE_SIZE,
50 PUBKEY_SIZE,
51 NONCE_SIZE,
52 PUBKEY_SIZE
53 ];
54 Ok(NFTAccount {
55 type_account: u8::from_le_bytes(*type_account),
56 owner: Pubkey::new_from_array(*owner),
57 stake: u8::from_le_bytes(*stake),
58 authority: Pubkey::new_from_array(*authority),
59 nonce: u8::from_le_bytes(*nonce),
60 create_account_programm: Pubkey::new_from_array(*create_account_programm),
61 })
62 }
63
64 fn pack_into_slice(&self, dst: &mut [u8]) {
66 let dst = array_mut_ref![dst, 0, NFT_ACCOUNT_SIZE];
67 let (
68 type_account_dst,
69 owner_dst,
70 stake_dst,
71 authority_dst,
72 nonce_dst,
73 create_account_programm_dst,
74 ) = mut_array_refs![
75 dst,
76 TYPE_SIZE,
77 PUBKEY_SIZE,
78 STAKE_SIZE,
79 PUBKEY_SIZE,
80 NONCE_SIZE,
81 PUBKEY_SIZE
82 ];
83 let NFTAccount {
84 type_account,
85 owner,
86 stake,
87 authority,
88 nonce,
89 create_account_programm,
90 } = self;
91 *type_account_dst = type_account.to_le_bytes();
92 owner_dst.copy_from_slice(owner.as_ref());
93 *stake_dst = stake.to_le_bytes();
94 authority_dst.copy_from_slice(authority.as_ref());
95 *nonce_dst = nonce.to_le_bytes();
96 create_account_programm_dst.copy_from_slice(create_account_programm.as_ref());
97 }
98}
99
100#[cfg(test)]
101mod tests {
102 use super::*;
103 use crate::constants::account_type::TYPE_ACCOUNT_NFT_ACCOUNT;
104
105 #[test]
106 fn test_pack_nft() {
107 let type_account = TYPE_ACCOUNT_NFT_ACCOUNT;
108 let owner = Pubkey::new_unique();
109 let stake = 0;
110 let authority = Pubkey::new_unique();
111 let nonce = 255;
112 let create_account_programm = Pubkey::new_unique();
113
114 let nft = NFTAccount {
115 type_account,
116 owner,
117 stake,
118 authority,
119 nonce,
120 create_account_programm,
121 };
122
123 let mut packed = [0u8; NFTAccount::LEN];
124
125 Pack::pack_into_slice(&nft, &mut packed[..]);
126 let unpacked = NFTAccount::unpack_from_slice(&packed).unwrap();
127 assert_eq!(nft, unpacked);
128 assert_eq!(unpacked.type_account, TYPE_ACCOUNT_NFT_ACCOUNT);
129 }
130}