1use serde::Deserialize;
2use solana_sdk::{
3 account::Account,
4 instruction::{AccountMeta, Instruction},
5 pubkey::Pubkey,
6};
7use std::{fs, path::Path};
8
9mod base64_deserialize;
10mod field_as_string;
11mod hex_deserialize;
12
13#[derive(Debug, Deserialize)]
14pub struct TestAccountMeta {
15 #[serde(with = "field_as_string")]
16 pub pubkey: Pubkey,
17 pub is_signer: bool,
18 pub is_writable: bool,
19}
20
21impl From<TestAccountMeta> for AccountMeta {
22 fn from(val: TestAccountMeta) -> Self {
23 AccountMeta {
24 pubkey: val.pubkey,
25 is_signer: val.is_signer,
26 is_writable: val.is_writable,
27 }
28 }
29}
30
31#[derive(Debug, Deserialize)]
32pub struct TestInstruction {
33 #[serde(with = "field_as_string")]
34 pub program_id: Pubkey,
35 pub accounts: Vec<TestAccountMeta>,
36 #[serde(with = "hex_deserialize")]
37 pub data: Vec<u8>,
38}
39
40impl From<TestInstruction> for Instruction {
41 fn from(val: TestInstruction) -> Self {
42 Instruction {
43 program_id: val.program_id,
44 accounts: val.accounts.into_iter().map(Into::into).collect(),
45 data: val.data,
46 }
47 }
48}
49
50#[derive(Debug, Deserialize)]
51pub struct TestAccount {
52 #[serde(with = "base64_deserialize")]
53 pub data: Vec<u8>,
54 pub executable: bool,
55 pub lamports: u64,
56 #[serde(with = "field_as_string")]
57 pub owner: Pubkey,
58 pub rent_epoch: u64,
59}
60
61impl From<TestAccount> for Account {
62 fn from(val: TestAccount) -> Self {
63 Account {
64 data: val.data,
65 lamports: val.lamports,
66 owner: val.owner,
67 executable: val.executable,
68 rent_epoch: val.rent_epoch,
69 }
70 }
71}
72
73pub fn read_instruction<P: AsRef<Path>>(ix_path: P) -> anyhow::Result<Instruction> {
74 let data = fs::read(ix_path).map_err(|e| anyhow::anyhow!("Couldn't read fixture: {e}"))?;
75
76 let ix = serde_json::from_slice::<TestInstruction>(&data)
77 .map_err(|e| anyhow::anyhow!("Couldn't deserialize fixture: {e}"))?;
78
79 Ok(ix.into())
80}
81
82pub fn read_account<P: AsRef<Path>>(acc_path: P) -> anyhow::Result<Account> {
83 let data = fs::read(acc_path).map_err(|e| anyhow::anyhow!("Couldn't read fixture: {e}"))?;
84
85 let acc = serde_json::from_slice::<TestAccount>(&data)
86 .map_err(|e| anyhow::anyhow!("Couldn't deserialize fixture: {e}"))?;
87
88 Ok(acc.into())
89}