1use serde::Serialize;
10
11#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
13#[serde(tag = "kind", rename_all = "snake_case")]
14pub enum Output {
15 Loaded {
17 steps: usize,
18 contracts: Vec<LoadedContract>,
20 },
21 Stop(Stop),
23 Message {
25 level: Level,
26 text: String,
27 #[serde(skip_serializing_if = "Option::is_none")]
28 note: Option<String>,
29 },
30 Breakpoint {
32 event: BreakpointEvent,
33 id: u32,
34 label: String,
35 },
36 Breakpoints {
37 breakpoints: Vec<BreakpointInfo>,
38 },
39 Backtrace {
40 #[serde(skip_serializing_if = "Option::is_none")]
43 warning: Option<String>,
44 #[serde(skip_serializing_if = "Option::is_none")]
45 note: Option<String>,
46 frames: Vec<FrameInfo>,
47 },
48 Listing {
49 path: String,
50 current_line: u64,
51 lines: Vec<ListedLine>,
52 },
53 Stack {
54 words: Vec<String>,
56 shown: usize,
58 },
59 Memory(MemoryInfo),
60 Storage {
61 #[serde(skip_serializing_if = "Option::is_none")]
62 address: Option<String>,
63 slots: Vec<SlotInfo>,
64 },
65 TransientStorage {
67 #[serde(skip_serializing_if = "Option::is_none")]
68 address: Option<String>,
69 slots: Vec<SlotInfo>,
70 },
71 Calldata {
72 bytes: usize,
73 data: String,
74 },
75 ReturnData {
77 bytes: usize,
78 data: String,
79 },
80 Variables {
82 #[serde(skip_serializing_if = "Option::is_none")]
83 warning: Option<String>,
84 pc: u64,
85 locals: Vec<VariableInfo>,
86 #[serde(skip_serializing_if = "Option::is_none")]
88 unavailable: Option<String>,
89 state: StateInfo,
90 #[serde(skip_serializing_if = "Vec::is_empty")]
92 transient: Vec<VariableInfo>,
93 },
94 Variable {
96 #[serde(skip_serializing_if = "Option::is_none")]
97 warning: Option<String>,
98 variable: VariableInfo,
99 },
100 Resources {
102 contracts: Vec<ResourceInfo>,
103 json: bool,
105 },
106 Help {
107 lines: Vec<String>,
108 },
109 Tui,
111 Quit,
113}
114
115#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
116#[serde(rename_all = "snake_case")]
117pub enum Level {
118 Info,
119 Warning,
120 Note,
122}
123
124#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
125pub struct LoadedContract {
126 pub name: String,
127 #[serde(skip_serializing_if = "Option::is_none")]
128 pub address: Option<String>,
129}
130
131#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
133#[serde(tag = "reason", rename_all = "snake_case")]
134pub enum StopReason {
135 Initial,
137 Moved,
139 Breakpoint {
140 id: u32,
141 label: String,
142 },
143 End,
145 Start,
147}
148
149#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
150pub struct Stop {
151 #[serde(flatten)]
152 pub reason: StopReason,
153 pub step: usize,
154 pub last_step: usize,
156 pub pc: u64,
157 pub op: String,
158 pub gas: u64,
159 #[serde(skip_serializing_if = "Option::is_none")]
161 pub location: Option<StopLocation>,
162 #[serde(skip_serializing_if = "Option::is_none")]
164 pub address: Option<String>,
165 pub has_source: bool,
168 #[serde(skip_serializing_if = "Option::is_none")]
170 pub stack: Option<Vec<String>>,
171 #[serde(skip_serializing_if = "Option::is_none")]
174 pub note: Option<String>,
175}
176
177#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
178pub struct StopLocation {
179 pub path: String,
180 pub line: u64,
181 #[serde(skip_serializing_if = "Option::is_none")]
182 pub function: Option<String>,
183 pub generated: bool,
185 #[serde(skip_serializing_if = "Option::is_none")]
186 pub text: Option<String>,
187}
188
189#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
190#[serde(rename_all = "snake_case")]
191pub enum BreakpointEvent {
192 Set,
193 Cleared,
194}
195
196#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
197pub struct BreakpointInfo {
198 pub id: u32,
199 pub label: String,
200}
201
202#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
203pub struct FrameInfo {
204 pub index: usize,
205 pub name: String,
207 pub arguments: Vec<ArgumentInfo>,
208 #[serde(skip_serializing_if = "Option::is_none")]
209 pub location: Option<String>,
210 #[serde(skip_serializing_if = "Option::is_none")]
212 pub address: Option<String>,
213 pub step: usize,
214 pub pc: u64,
215 #[serde(skip_serializing_if = "Option::is_none")]
217 pub kind: Option<String>,
218}
219
220#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
221pub struct ArgumentInfo {
222 pub name: String,
223 pub value: String,
224}
225
226#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
227pub struct ListedLine {
228 pub line: u64,
229 pub text: String,
230 pub current: bool,
231}
232
233#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
234pub struct MemoryInfo {
235 pub total: usize,
237 pub start: usize,
238 pub end: usize,
239 pub words: Vec<MemoryWord>,
241}
242
243#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
244pub struct MemoryWord {
245 pub offset: usize,
246 pub hex: String,
247}
248
249#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
250pub struct SlotInfo {
251 pub slot: String,
252 pub value: String,
253 #[serde(skip_serializing_if = "Option::is_none")]
255 pub was: Option<String>,
256}
257
258#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
259pub struct VariableInfo {
260 pub name: String,
261 pub ty: String,
262 pub value: String,
263 #[serde(skip_serializing_if = "Option::is_none")]
264 pub raw: Option<String>,
265 pub status: ValueStatus,
266 #[serde(skip_serializing_if = "Option::is_none")]
269 pub place: Option<String>,
270}
271
272#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
273#[serde(rename_all = "snake_case")]
274pub enum ValueStatus {
275 Decoded,
276 Raw,
277 Unavailable,
278}
279
280#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
282#[serde(tag = "status", rename_all = "snake_case")]
283pub enum StateInfo {
284 Variables {
285 variables: Vec<VariableInfo>,
286 },
287 None,
289 NoLayout,
291 NoStorage,
293}
294
295#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
296pub struct ResourceInfo {
297 pub name: String,
298 #[serde(skip_serializing_if = "Option::is_none")]
299 pub address: Option<String>,
300 pub environment: String,
301 pub sources: Vec<String>,
302}