1use {
4 crate::{
5 account::{Account, AccountSharedData},
6 instruction::InstructionError,
7 },
8 bincode::ErrorKind,
9 std::cell::Ref,
10};
11
12pub trait StateMut<T> {
14 fn state(&self) -> Result<T, InstructionError>;
15 fn set_state(&mut self, state: &T) -> Result<(), InstructionError>;
16}
17pub trait State<T> {
18 fn state(&self) -> Result<T, InstructionError>;
19 fn set_state(&self, state: &T) -> Result<(), InstructionError>;
20}
21
22impl<T> StateMut<T> for Account
23where
24 T: serde::Serialize + serde::de::DeserializeOwned,
25{
26 fn state(&self) -> Result<T, InstructionError> {
27 self.deserialize_data()
28 .map_err(|_| InstructionError::InvalidAccountData)
29 }
30 fn set_state(&mut self, state: &T) -> Result<(), InstructionError> {
31 self.serialize_data(state).map_err(|err| match *err {
32 ErrorKind::SizeLimit => InstructionError::AccountDataTooSmall,
33 _ => InstructionError::GenericError,
34 })
35 }
36}
37
38impl<T> StateMut<T> for AccountSharedData
39where
40 T: serde::Serialize + serde::de::DeserializeOwned,
41{
42 fn state(&self) -> Result<T, InstructionError> {
43 self.deserialize_data()
44 .map_err(|_| InstructionError::InvalidAccountData)
45 }
46 fn set_state(&mut self, state: &T) -> Result<(), InstructionError> {
47 self.serialize_data(state).map_err(|err| match *err {
48 ErrorKind::SizeLimit => InstructionError::AccountDataTooSmall,
49 _ => InstructionError::GenericError,
50 })
51 }
52}
53
54impl<T> StateMut<T> for Ref<'_, AccountSharedData>
55where
56 T: serde::Serialize + serde::de::DeserializeOwned,
57{
58 fn state(&self) -> Result<T, InstructionError> {
59 self.deserialize_data()
60 .map_err(|_| InstructionError::InvalidAccountData)
61 }
62 fn set_state(&mut self, _state: &T) -> Result<(), InstructionError> {
63 panic!("illegal");
64 }
65}
66
67#[cfg(test)]
68mod tests {
69 use {
70 super::*,
71 crate::{account::AccountSharedData, pubkey::Pubkey},
72 };
73
74 #[test]
75 fn test_account_state() {
76 let state = 42u64;
77
78 assert!(AccountSharedData::default().set_state(&state).is_err());
79 let res = AccountSharedData::default().state() as Result<u64, InstructionError>;
80 assert!(res.is_err());
81
82 let mut account = AccountSharedData::new(0, std::mem::size_of::<u64>(), &Pubkey::default());
83
84 assert!(account.set_state(&state).is_ok());
85 let stored_state: u64 = account.state().unwrap();
86 assert_eq!(stored_state, state);
87 }
88}