use crate::id;
use borsh::{BorshDeserialize, BorshSerialize};
use solana_program::{
instruction::{AccountMeta, Instruction},
pubkey::Pubkey,
};
#[derive(Clone, Debug, BorshSerialize, BorshDeserialize, PartialEq)]
pub enum RecordInstruction {
Initialize,
Write {
offset: u64,
data: Vec<u8>,
},
SetAuthority,
CloseAccount,
}
pub fn initialize(record_account: &Pubkey, authority: &Pubkey) -> Instruction {
Instruction::new_with_borsh(
id(),
&RecordInstruction::Initialize,
vec![
AccountMeta::new(*record_account, false),
AccountMeta::new_readonly(*authority, false),
],
)
}
pub fn write(record_account: &Pubkey, signer: &Pubkey, offset: u64, data: Vec<u8>) -> Instruction {
Instruction::new_with_borsh(
id(),
&RecordInstruction::Write { offset, data },
vec![
AccountMeta::new(*record_account, false),
AccountMeta::new_readonly(*signer, true),
],
)
}
pub fn set_authority(
record_account: &Pubkey,
signer: &Pubkey,
new_authority: &Pubkey,
) -> Instruction {
Instruction::new_with_borsh(
id(),
&RecordInstruction::SetAuthority,
vec![
AccountMeta::new(*record_account, false),
AccountMeta::new_readonly(*signer, true),
AccountMeta::new_readonly(*new_authority, false),
],
)
}
pub fn close_account(record_account: &Pubkey, signer: &Pubkey, receiver: &Pubkey) -> Instruction {
Instruction::new_with_borsh(
id(),
&RecordInstruction::CloseAccount,
vec![
AccountMeta::new(*record_account, false),
AccountMeta::new_readonly(*signer, true),
AccountMeta::new(*receiver, false),
],
)
}
#[cfg(test)]
mod tests {
use super::*;
use crate::state::tests::TEST_DATA;
use solana_program::program_error::ProgramError;
#[test]
fn serialize_initialize() {
let instruction = RecordInstruction::Initialize;
let expected = vec![0];
assert_eq!(instruction.try_to_vec().unwrap(), expected);
assert_eq!(
RecordInstruction::try_from_slice(&expected).unwrap(),
instruction
);
}
#[test]
fn serialize_write() {
let data = TEST_DATA.try_to_vec().unwrap();
let offset = 0u64;
let instruction = RecordInstruction::Write {
offset: 0,
data: data.clone(),
};
let mut expected = vec![1];
expected.extend_from_slice(&offset.to_le_bytes());
expected.append(&mut data.try_to_vec().unwrap());
assert_eq!(instruction.try_to_vec().unwrap(), expected);
assert_eq!(
RecordInstruction::try_from_slice(&expected).unwrap(),
instruction
);
}
#[test]
fn serialize_set_authority() {
let instruction = RecordInstruction::SetAuthority;
let expected = vec![2];
assert_eq!(instruction.try_to_vec().unwrap(), expected);
assert_eq!(
RecordInstruction::try_from_slice(&expected).unwrap(),
instruction
);
}
#[test]
fn serialize_close_account() {
let instruction = RecordInstruction::CloseAccount;
let expected = vec![3];
assert_eq!(instruction.try_to_vec().unwrap(), expected);
assert_eq!(
RecordInstruction::try_from_slice(&expected).unwrap(),
instruction
);
}
#[test]
fn deserialize_invalid_instruction() {
let mut expected = vec![12];
expected.append(&mut TEST_DATA.try_to_vec().unwrap());
let err: ProgramError = RecordInstruction::try_from_slice(&expected)
.unwrap_err()
.into();
assert!(matches!(err, ProgramError::BorshIoError(_)));
}
}