chisel/
cmd.rs

1//! ChiselCommand
2//!
3//! This module holds the [ChiselCommand] enum, which contains all builtin commands that
4//! can be executed within the REPL.
5
6use crate::prelude::ChiselDispatcher;
7use std::{error::Error, str::FromStr};
8use strum::EnumIter;
9
10/// Builtin chisel command variants
11#[derive(Debug, EnumIter)]
12pub enum ChiselCommand {
13    /// Print helpful information about chisel
14    Help,
15    /// Quit the REPL
16    Quit,
17    /// Clear the current session source
18    Clear,
19    /// Print the generated source contract
20    Source,
21    /// Save the current session to the cache
22    /// Takes: `<session-id>`
23    Save,
24    /// Load a previous session from cache
25    /// Takes: `<session-id>`
26    ///
27    /// WARNING: This will overwrite the current session (though the current session will be
28    /// optimistically cached)
29    Load,
30    /// List all cached sessions
31    ListSessions,
32    /// Clear the cache of all stored sessions
33    ClearCache,
34    /// Fork an RPC in the current session
35    /// Takes <fork-url|env-var|rpc_endpoints-alias>
36    Fork,
37    /// Enable / disable traces for the current session
38    Traces,
39    /// Set calldata (`msg.data`) for the current session (appended after function selector)
40    Calldata,
41    /// Dump the raw memory
42    MemDump,
43    /// Dump the raw stack
44    StackDump,
45    /// Export the current REPL session source to a Script file
46    Export,
47    /// Fetch an interface of a verified contract on Etherscan
48    /// Takes: `<addr> <interface-name>`
49    Fetch,
50    /// Executes a shell command
51    Exec,
52    /// Display the raw value of a variable's stack allocation.
53    RawStack,
54    /// Open the current session in an editor
55    Edit,
56}
57
58/// Attempt to convert a string slice to a `ChiselCommand`
59impl FromStr for ChiselCommand {
60    type Err = Box<dyn Error>;
61
62    fn from_str(s: &str) -> Result<Self, Self::Err> {
63        match s.to_lowercase().as_ref() {
64            "help" | "h" => Ok(Self::Help),
65            "quit" | "q" => Ok(Self::Quit),
66            "clear" | "c" => Ok(Self::Clear),
67            "source" | "so" => Ok(Self::Source),
68            "save" | "s" => Ok(Self::Save),
69            "list" | "ls" => Ok(Self::ListSessions),
70            "load" | "l" => Ok(Self::Load),
71            "clearcache" | "cc" => Ok(Self::ClearCache),
72            "fork" | "f" => Ok(Self::Fork),
73            "traces" | "t" => Ok(Self::Traces),
74            "calldata" | "cd" => Ok(Self::Calldata),
75            "memdump" | "md" => Ok(Self::MemDump),
76            "stackdump" | "sd" => Ok(Self::StackDump),
77            "export" | "ex" => Ok(Self::Export),
78            "fetch" | "fe" => Ok(Self::Fetch),
79            "exec" | "e" => Ok(Self::Exec),
80            "rawstack" | "rs" => Ok(Self::RawStack),
81            "edit" => Ok(Self::Edit),
82            _ => Err(ChiselDispatcher::make_error(format!(
83                "Unknown command \"{s}\"! See available commands with `!help`.",
84            ))
85            .into()),
86        }
87    }
88}
89
90/// A category for [ChiselCommand]s
91#[derive(Debug, EnumIter)]
92pub enum CmdCategory {
93    /// General category
94    General,
95    /// Session category
96    Session,
97    /// Environment category
98    Env,
99    /// Debug category
100    Debug,
101}
102
103impl core::fmt::Display for CmdCategory {
104    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
105        let string = match self {
106            Self::General => "General",
107            Self::Session => "Session",
108            Self::Env => "Environment",
109            Self::Debug => "Debug",
110        };
111        f.write_str(string)
112    }
113}
114
115/// A command descriptor type
116pub type CmdDescriptor = (&'static [&'static str], &'static str, CmdCategory);
117
118/// Convert a `ChiselCommand` into a `CmdDescriptor` tuple
119impl From<ChiselCommand> for CmdDescriptor {
120    fn from(cmd: ChiselCommand) -> Self {
121        match cmd {
122            // General
123            ChiselCommand::Help => (&["help", "h"], "Display all commands", CmdCategory::General),
124            ChiselCommand::Quit => (&["quit", "q"], "Quit Chisel", CmdCategory::General),
125            ChiselCommand::Exec => (&["exec <command> [args]", "e <command> [args]"], "Execute a shell command and print the output", CmdCategory::General),
126            // Session
127            ChiselCommand::Clear => (&["clear", "c"], "Clear current session source", CmdCategory::Session),
128            ChiselCommand::Source => (&["source", "so"], "Display the source code of the current session", CmdCategory::Session),
129            ChiselCommand::Save => (&["save [id]", "s [id]"], "Save the current session to cache", CmdCategory::Session),
130            ChiselCommand::Load => (&["load <id>", "l <id>"], "Load a previous session ID from cache", CmdCategory::Session),
131            ChiselCommand::ListSessions => (&["list", "ls"], "List all cached sessions", CmdCategory::Session),
132            ChiselCommand::ClearCache => (&["clearcache", "cc"], "Clear the chisel cache of all stored sessions", CmdCategory::Session),
133            ChiselCommand::Export => (&["export", "ex"], "Export the current session source to a script file", CmdCategory::Session),
134            ChiselCommand::Fetch => (&["fetch <addr> <name>", "fe <addr> <name>"], "Fetch the interface of a verified contract on Etherscan", CmdCategory::Session),
135            // Environment
136            ChiselCommand::Fork => (&["fork <url>", "f <url>"], "Fork an RPC for the current session. Supply 0 arguments to return to a local network", CmdCategory::Env),
137            ChiselCommand::Traces => (&["traces", "t"], "Enable / disable traces for the current session", CmdCategory::Env),
138            ChiselCommand::Calldata => (&["calldata [data]", "cd [data]"], "Set calldata (`msg.data`) for the current session (appended after function selector). Clears it if no argument provided.", CmdCategory::Env),
139            // Debug
140            ChiselCommand::MemDump => (&["memdump", "md"], "Dump the raw memory of the current state", CmdCategory::Debug),
141            ChiselCommand::StackDump => (&["stackdump", "sd"], "Dump the raw stack of the current state", CmdCategory::Debug),
142            ChiselCommand::Edit => (&["edit"], "Open the current session in an editor", CmdCategory::Session),
143            ChiselCommand::RawStack => (&["rawstack <var>", "rs <var>"], "Display the raw value of a variable's stack allocation. For variables that are > 32 bytes in length, this will display their memory pointer.", CmdCategory::Debug),
144        }
145    }
146}