carbon_test_utils/
lib.rs

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