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