1use gear_core::{memory::PageBuf, pages::GearPage};
7pub use nonempty::NonEmpty;
8use parity_scale_codec::{Decode, Encode};
9use path_clean::PathClean;
10use serde::{Deserialize, Serialize};
11use std::{
12 env, fs,
13 path::Path,
14 time::{Duration, SystemTime, UNIX_EPOCH},
15};
16
17pub mod codegen;
18
19pub trait RingGet<V> {
26 fn ring_get(&self, index: usize) -> &V;
28}
29
30impl<V> RingGet<V> for NonEmpty<V> {
31 fn ring_get(&self, index: usize) -> &V {
32 self.get(index % self.len()).expect("guaranteed to be some")
34 }
35}
36
37pub fn now_millis() -> u64 {
39 now_duration().as_millis() as u64
40}
41
42pub fn now_micros() -> u128 {
44 now_duration().as_micros()
45}
46
47pub fn now_duration() -> Duration {
49 SystemTime::now()
50 .duration_since(UNIX_EPOCH)
51 .expect("Internal error: current time before UNIX Epoch")
52}
53
54pub fn init_default_logger() {
64 let _ = tracing_subscriber::fmt::try_init();
65}
66
67#[derive(Serialize, Deserialize)]
69pub struct MemoryPageDump {
70 page: u32,
71 data: Option<String>,
72}
73
74impl MemoryPageDump {
75 pub fn new(page_number: GearPage, page_data: PageBuf) -> MemoryPageDump {
76 let mut data_vec = vec![];
77 page_data.encode_to(&mut data_vec);
78 let data = data_vec
79 .iter()
80 .any(|&byte| byte != 0)
81 .then(|| hex::encode(data_vec));
82
83 MemoryPageDump {
84 page: page_number.into(),
85 data,
86 }
87 }
88
89 pub fn into_gear_page(self) -> (GearPage, PageBuf) {
90 let page_buf = if let Some(page_hex) = self.data {
91 let data = hex::decode(page_hex).expect("Unexpected memory page data encoding");
92 PageBuf::decode(&mut &*data).expect("Invalid PageBuf data found")
93 } else {
94 PageBuf::new_zeroed()
95 };
96 (
97 GearPage::try_from(self.page)
98 .unwrap_or_else(|_| panic!("Couldn't decode GearPage from u32: {}", self.page)),
99 page_buf,
100 )
101 }
102}
103
104#[derive(Serialize, Deserialize, Default)]
106pub struct ProgramMemoryDump {
107 pub balance: u128,
108 pub reserved_balance: u128,
109 pub pages: Vec<MemoryPageDump>,
110}
111
112impl ProgramMemoryDump {
113 pub fn save_to_file(&self, path: impl AsRef<Path>) {
114 let path = env::current_dir()
115 .expect("Unable to get root directory of the project")
116 .join(path)
117 .clean();
118
119 if let Some(parent) = path.parent() {
120 fs::create_dir_all(parent)
121 .unwrap_or_else(|_| panic!("Couldn't create folder {}", parent.display()));
122 }
123
124 let data =
125 serde_json::to_string(&self).expect("Failed to serialize ProgramMemoryDump to JSON");
126
127 fs::write(&path, data).unwrap_or_else(|_| panic!("Failed to write file {path:?}"));
128 }
129
130 pub fn load_from_file(path: impl AsRef<Path>) -> ProgramMemoryDump {
131 let path = env::current_dir()
132 .expect("Unable to get root directory of the project")
133 .join(path)
134 .clean();
135
136 let json =
137 fs::read_to_string(&path).unwrap_or_else(|_| panic!("Failed to read file {path:?}"));
138
139 serde_json::from_str(&json)
140 .unwrap_or_else(|_| panic!("Failed to deserialize {path:?} as ProgramMemoryDump"))
141 }
142}