mollusk_svm_fuzz_fs/
lib.rs1use {
2 prost::Message,
3 serde::{de::DeserializeOwned, Serialize},
4 std::{
5 fs::{self, File},
6 io::{Read, Write},
7 path::Path,
8 },
9};
10
11pub trait SerializableFixture: Default + DeserializeOwned + Message + Serialize + Sized {
13 fn decode(blob: &[u8]) -> Self {
15 <Self as Message>::decode(blob)
16 .unwrap_or_else(|err| panic!("Failed to decode fixture: {}", err))
17 }
18
19 fn encode(&self) -> Vec<u8> {
21 let mut buf = Vec::new();
22 Message::encode(self, &mut buf).expect("Failed to encode fixture");
23 buf
24 }
25
26 fn hash(&self) -> solana_keccak_hasher::Hash;
28}
29
30pub trait IntoSerializableFixture {
32 type Fixture: SerializableFixture;
33
34 fn into(self) -> Self::Fixture;
35}
36
37pub struct FsHandler<SF>
38where
39 SF: SerializableFixture,
40{
41 serializable_fixture: SF,
42}
43
44impl<SF> FsHandler<SF>
45where
46 SF: SerializableFixture,
47{
48 pub fn new<T: IntoSerializableFixture<Fixture = SF>>(fix: T) -> Self {
49 let serializable_fixture = fix.into();
50 Self {
51 serializable_fixture,
52 }
53 }
54
55 pub fn dump_to_blob_file(&self, dir: &str) {
58 let blob = SerializableFixture::encode(&self.serializable_fixture);
59
60 let hash = self.serializable_fixture.hash();
61 let file_name = format!("instr-{}.fix", bs58::encode(hash).into_string());
62
63 write_file(Path::new(dir), &file_name, &blob);
64 }
65
66 pub fn dump_to_json_file(self, dir_path: &str) {
69 let json = serde_json::to_string_pretty(&self.serializable_fixture)
70 .expect("Failed to serialize fixture to JSON");
71
72 let hash = self.serializable_fixture.hash();
73 let file_name = format!("instr-{}.json", bs58::encode(hash).into_string());
74
75 write_file(Path::new(dir_path), &file_name, json.as_bytes());
76 }
77
78 pub fn load_from_blob_file(file_path: &str) -> SF {
80 if !file_path.ends_with(".fix") {
81 panic!("Invalid fixture file extension: {}", file_path);
82 }
83 let mut file = File::open(file_path).expect("Failed to open fixture file");
84 let mut blob = Vec::new();
85 file.read_to_end(&mut blob)
86 .expect("Failed to read fixture file");
87 <SF as SerializableFixture>::decode(&blob)
88 }
89
90 pub fn load_from_json_file(file_path: &str) -> SF {
92 if !file_path.ends_with(".json") {
93 panic!("Invalid fixture file extension: {}", file_path);
94 }
95 let mut file = File::open(file_path).expect("Failed to open fixture file");
96 let mut json = String::new();
97 file.read_to_string(&mut json)
98 .expect("Failed to read fixture file");
99 serde_json::from_str(&json).expect("Failed to deserialize fixture from JSON")
100 }
101}
102
103fn write_file(dir: &Path, file_name: &str, data: &[u8]) {
104 fs::create_dir_all(dir).expect("Failed to create directory");
105 let file_path = dir.join(file_name);
106 let mut file = File::create(file_path).unwrap();
107 file.write_all(data)
108 .expect("Failed to write fixture to file");
109}