ntoken_solana_models/states/
turing_machine.rs1use crate::constants::account_type::{TYPE_ACCOUNT_TRIGGUER_TURING_MACHINE_ACCOUNT, TYPE_ACCOUNT_TURING_MACHINE_ACCOUNT};
3use crate::constants::{
4 account_size::SPLU_SECONDARY_STRUCT_LEN,
5 account_size::TURING_MACHINE_ACCOUNT_PREFIX,
6 constant::PUBKEY_SIZE
7};
8use arrayref::{array_mut_ref, array_ref, array_refs, mut_array_refs};
9use serde::{Deserialize, Serialize};
10use solana_program::entrypoint::ProgramResult;
11use solana_program::{
12 program_error::ProgramError,
13 program_pack::Sealed,
14 pubkey::Pubkey,
15};
16use crate::error::PortfolioError;
17
18const TYPE_SIZE: usize = 1;
19const STATE_SIZE: usize = 1;
20const AMOUNT_SIZE: usize = 8;
21const VERSION_SIZE: usize = 1;
22const DATE_SIZE:usize = 8;
23
24#[repr(C)]
26#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
27pub struct SpluStateSecondaryStruct {
28 pub splu_secondary_address: Pubkey,
30 pub splu_state: u8,
32 pub splu_secondary_temporal: Pubkey,
34}
35
36impl SpluStateSecondaryStruct {
37 pub fn update_state_splu(&mut self) -> ProgramResult {
39 self.splu_state = self
40 .splu_state
41 .checked_add(1)
42 .ok_or(PortfolioError::InvalidState)?;
43
44 Ok(())
45 }
46
47 pub fn update_state_splu_with_param(&mut self, state: u8) -> ProgramResult {
49 self.splu_state = state;
50 Ok(())
51 }
52
53 pub fn reset_splu_secondary(&mut self) -> ProgramResult {
55 self.splu_state = 0;
56 Ok(())
57 }
58
59 pub fn update_splu_sec_tmp(&mut self, splu_sec_tmp: Pubkey) -> ProgramResult {
61 self.splu_secondary_temporal = splu_sec_tmp;
62 Ok(())
63 }
64}
65
66#[repr(C)]
68#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
69pub struct TuringMachineAccount {
70 pub type_account: u8,
72 pub owner: Pubkey,
74 pub splm_n_asset: Pubkey,
76 pub state: u8,
78 pub amount: u64,
80 pub version: u8,
82 pub date: i64,
84 pub splu_state_list: Vec<SpluStateSecondaryStruct>,
86}
87
88impl Sealed for TuringMachineAccount {}
89
90pub trait IsInitializedTuringMachine {
91 fn is_initialized(&self) -> bool;
93}
94impl IsInitializedTuringMachine for TuringMachineAccount {
95 fn is_initialized(&self) -> bool {
96 return (self.type_account == TYPE_ACCOUNT_TRIGGUER_TURING_MACHINE_ACCOUNT) || (self.type_account == TYPE_ACCOUNT_TURING_MACHINE_ACCOUNT);
97 }
98}
99pub trait PackTuringMachineAccount {
101 fn unpack_turing_machine_account(src: &[u8]) -> Result<TuringMachineAccount, ProgramError>;
103 fn pack_turing_machine_account(&self, dst: &mut [u8]);
105}
106
107impl PackTuringMachineAccount for TuringMachineAccount {
108 fn unpack_turing_machine_account(src: &[u8]) -> Result<Self, ProgramError> {
111 let numbre_splu_state =
112 (&src.len() - TURING_MACHINE_ACCOUNT_PREFIX) / SPLU_SECONDARY_STRUCT_LEN;
113 let len_splu_data = &src.len() - TURING_MACHINE_ACCOUNT_PREFIX;
114
115 let src_fix = array_ref![&src, 0, TURING_MACHINE_ACCOUNT_PREFIX];
116
117 let (type_account, owner, splm_n_asset, state, amount, version, date) = array_refs![
118 src_fix,
119 TYPE_SIZE,
120 PUBKEY_SIZE,
121 PUBKEY_SIZE,
122 STATE_SIZE,
123 AMOUNT_SIZE,
124 VERSION_SIZE,
125 DATE_SIZE
126 ];
127
128 let mut splu_vec: Vec<SpluStateSecondaryStruct> = Vec::with_capacity(numbre_splu_state);
129
130 let list_splu_data = &src[TURING_MACHINE_ACCOUNT_PREFIX
131 ..TURING_MACHINE_ACCOUNT_PREFIX + (len_splu_data) as usize];
132
133 let mut offset = 0;
135 for _ in 0..numbre_splu_state {
136 let splu_secondary = array_ref![list_splu_data, offset, SPLU_SECONDARY_STRUCT_LEN];
137 #[allow(clippy::ptr_offset_with_cast)]
138 let (splu_secondary_address, splu_state,splu_secondary_temporal) = array_refs![splu_secondary, PUBKEY_SIZE, 1,PUBKEY_SIZE];
139 splu_vec.push(SpluStateSecondaryStruct {
140 splu_secondary_address: Pubkey::new_from_array(*splu_secondary_address),
141 splu_state: u8::from_le_bytes(*splu_state),
142 splu_secondary_temporal: Pubkey::new_from_array(*splu_secondary_temporal),
143 });
144 offset += SPLU_SECONDARY_STRUCT_LEN;
145 }
146 Ok(TuringMachineAccount {
147 type_account: u8::from_le_bytes(*type_account),
148 owner: Pubkey::new_from_array(*owner),
149 splm_n_asset: Pubkey::new_from_array(*splm_n_asset),
150 state: u8::from_le_bytes(*state),
151 amount: u64::from_le_bytes(*amount),
152 version: u8::from_le_bytes(*version),
153 date: i64::from_le_bytes(*date),
154 splu_state_list: splu_vec.to_vec(),
155 })
156 }
157
158 fn pack_turing_machine_account(&self, dst: &mut [u8]) {
160 let dst_tmp = array_mut_ref![dst, 0, TURING_MACHINE_ACCOUNT_PREFIX];
161 let (type_account_dst, owner_dst, splm_n_asset_dst, state_dst, amount_dst, version_dst,date_dst) = mut_array_refs![
162 dst_tmp,
163 TYPE_SIZE,
164 PUBKEY_SIZE,
165 PUBKEY_SIZE,
166 STATE_SIZE,
167 AMOUNT_SIZE,
168 VERSION_SIZE,
169 DATE_SIZE
170 ];
171 let TuringMachineAccount {
172 type_account,
173 owner,
174 splm_n_asset,
175 state,
176 amount,
177 version,
178 date,
179 splu_state_list,
180 } = self;
181
182 let splu_vec_tmp = bincode::serialize(&splu_state_list).unwrap();
183 let len_splu = splu_vec_tmp.len();
184 let nbre_splu = (len_splu - 8) / SPLU_SECONDARY_STRUCT_LEN;
185 let len_slu_reel = nbre_splu * SPLU_SECONDARY_STRUCT_LEN;
186 let mut splu_data_tmp = [0; SPLU_SECONDARY_STRUCT_LEN * 10]; splu_data_tmp[0..len_slu_reel as usize].clone_from_slice(&splu_vec_tmp[8..len_splu]); *type_account_dst = type_account.to_le_bytes();
191 owner_dst.copy_from_slice(owner.as_ref());
192 splm_n_asset_dst.copy_from_slice(splm_n_asset.as_ref());
193 *state_dst = state.to_le_bytes();
194 *amount_dst = amount.to_le_bytes();
195 *version_dst = version.to_le_bytes();
196 *date_dst = date.to_le_bytes();
197 dst[TURING_MACHINE_ACCOUNT_PREFIX..TURING_MACHINE_ACCOUNT_PREFIX + len_slu_reel as usize]
198 .copy_from_slice(&splu_data_tmp[0..len_slu_reel]);
199 }
200}
201
202#[cfg(test)]
203mod tests {
204 use super::*;
205 use crate::constants::account_type::TYPE_ACCOUNT_TURING_MACHINE_ACCOUNT;
206
207 #[test]
208 fn test_pack_turing_account() {
209 let type_account = TYPE_ACCOUNT_TURING_MACHINE_ACCOUNT;
210 let owner = Pubkey::new_unique();
211 let state = 0;
212 let splm_n_asset = Pubkey::new_unique();
213 let amount = 2;
214 let version = 1;
215 let date = 234;
216
217 let splu_struct = SpluStateSecondaryStruct {
218 splu_secondary_address: Pubkey::new_unique(),
219 splu_state: 0,
220 splu_secondary_temporal: Pubkey::new_unique(),
221 };
222
223 let mut splu_state_list = Vec::new();
224 splu_state_list.push(splu_struct);
225 let turing = TuringMachineAccount {
226 type_account,
227 owner,
228 splm_n_asset,
229 state,
230 amount,
231 version,
232 date,
233 splu_state_list,
234 };
235
236 const LEN: usize = TURING_MACHINE_ACCOUNT_PREFIX + (SPLU_SECONDARY_STRUCT_LEN * 1); let mut packed = [0u8; LEN];
238
239 TuringMachineAccount::pack_turing_machine_account(&turing, &mut packed[..]);
240 let unpacked = TuringMachineAccount::unpack_turing_machine_account(&packed).unwrap();
241 assert_eq!(turing, unpacked);
242 assert_eq!(unpacked.type_account, TYPE_ACCOUNT_TURING_MACHINE_ACCOUNT);
243 }
244}