1pub mod escrow_constraints;
2pub mod transfer_effects;
3pub mod trifle;
4
5use std::io::ErrorKind;
6
7use borsh::{maybestd::io::Error as BorshError, BorshDeserialize, BorshSerialize};
8use mpl_token_metadata::assertions::assert_owned_by;
9use num_derive::FromPrimitive;
10use num_traits::FromPrimitive;
11use solana_program::{account_info::AccountInfo, program_error::ProgramError};
12
13use crate::error::TrifleError;
14
15pub const TRIFLE_SEED: &str = "trifle";
16pub const ESCROW_SEED: &str = "escrow";
17pub const FREEZE_AUTHORITY: &str = "freeze_authority";
18
19#[repr(C)]
20#[derive(BorshSerialize, BorshDeserialize, PartialEq, Eq, Debug, Clone, Copy, FromPrimitive)]
21pub enum Key {
22 Uninitialized,
23 EscrowConstraintModel,
24 Trifle,
25}
26
27pub trait SolanaAccount: BorshDeserialize {
28 fn key() -> Key;
29
30 fn size() -> usize;
31
32 fn is_correct_account_type(data: &[u8], data_type: Key) -> bool {
33 let key: Option<Key> = Key::from_u8(data[0]);
34 match key {
35 Some(key) => key == data_type || key == Key::Uninitialized,
36 None => false,
37 }
38 }
39
40 fn pad_length(buf: &mut Vec<u8>) -> Result<(), TrifleError> {
41 let padding_length = Self::size()
42 .checked_sub(buf.len())
43 .ok_or(TrifleError::NumericalOverflow)?;
44 buf.extend(vec![0; padding_length]);
45 Ok(())
46 }
47
48 fn safe_deserialize(mut data: &[u8]) -> Result<Self, BorshError> {
49 if !Self::is_correct_account_type(data, Self::key()) {
50 return Err(BorshError::new(ErrorKind::Other, "DataTypeMismatch"));
51 }
52
53 let result = Self::deserialize(&mut data)?;
54
55 Ok(result)
56 }
57
58 fn from_account_info(a: &AccountInfo) -> Result<Self, ProgramError>
59where {
60 let ua = Self::safe_deserialize(&a.data.borrow_mut())
61 .map_err(|_| TrifleError::DataTypeMismatch)?;
62
63 assert_owned_by(a, &crate::id())?;
65
66 Ok(ua)
67 }
68}