//! useful extras for Account state use crate::{account::Account, instruction::InstructionError}; use bincode::ErrorKind; /// Convenience trait to covert bincode errors to instruction errors. pub trait StateMut { fn state(&self) -> Result; fn set_state(&mut self, state: &T) -> Result<(), InstructionError>; } pub trait State { fn state(&self) -> Result; fn set_state(&self, state: &T) -> Result<(), InstructionError>; } impl StateMut for Account where T: serde::Serialize + serde::de::DeserializeOwned, { fn state(&self) -> Result { self.deserialize_data() .map_err(|_| InstructionError::InvalidAccountData) } fn set_state(&mut self, state: &T) -> Result<(), InstructionError> { self.serialize_data(state).map_err(|err| match *err { ErrorKind::SizeLimit => InstructionError::AccountDataTooSmall, _ => InstructionError::GenericError, }) } } #[cfg(test)] mod tests { use super::*; use crate::{account::Account, pubkey::Pubkey}; #[test] fn test_account_state() { let state = 42u64; assert!(Account::default().set_state(&state).is_err()); let res = Account::default().state() as Result; assert!(res.is_err()); let mut account = Account::new(0, std::mem::size_of::(), &Pubkey::default()); assert!(account.set_state(&state).is_ok()); let stored_state: u64 = account.state().unwrap(); assert_eq!(stored_state, state); } }