use crate::prelude::ChiselDispatcher;
use std::{error::Error, str::FromStr};
use strum::EnumIter;
#[derive(Debug, EnumIter)]
pub enum ChiselCommand {
Help,
Quit,
Clear,
Source,
Save,
Load,
ListSessions,
ClearCache,
Fork,
Traces,
Calldata,
MemDump,
StackDump,
Export,
Fetch,
Exec,
RawStack,
Edit,
}
impl FromStr for ChiselCommand {
type Err = Box<dyn Error>;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s.to_lowercase().as_ref() {
"help" | "h" => Ok(Self::Help),
"quit" | "q" => Ok(Self::Quit),
"clear" | "c" => Ok(Self::Clear),
"source" | "so" => Ok(Self::Source),
"save" | "s" => Ok(Self::Save),
"list" | "ls" => Ok(Self::ListSessions),
"load" | "l" => Ok(Self::Load),
"clearcache" | "cc" => Ok(Self::ClearCache),
"fork" | "f" => Ok(Self::Fork),
"traces" | "t" => Ok(Self::Traces),
"calldata" | "cd" => Ok(Self::Calldata),
"memdump" | "md" => Ok(Self::MemDump),
"stackdump" | "sd" => Ok(Self::StackDump),
"export" | "ex" => Ok(Self::Export),
"fetch" | "fe" => Ok(Self::Fetch),
"exec" | "e" => Ok(Self::Exec),
"rawstack" | "rs" => Ok(Self::RawStack),
"edit" => Ok(Self::Edit),
_ => Err(ChiselDispatcher::make_error(format!(
"Unknown command \"{s}\"! See available commands with `!help`.",
))
.into()),
}
}
}
#[derive(Debug, EnumIter)]
pub enum CmdCategory {
General,
Session,
Env,
Debug,
}
impl core::fmt::Display for CmdCategory {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
let string = match self {
Self::General => "General",
Self::Session => "Session",
Self::Env => "Environment",
Self::Debug => "Debug",
};
f.write_str(string)
}
}
pub type CmdDescriptor = (&'static [&'static str], &'static str, CmdCategory);
impl From<ChiselCommand> for CmdDescriptor {
fn from(cmd: ChiselCommand) -> Self {
match cmd {
ChiselCommand::Help => (&["help", "h"], "Display all commands", CmdCategory::General),
ChiselCommand::Quit => (&["quit", "q"], "Quit Chisel", CmdCategory::General),
ChiselCommand::Exec => (&["exec <command> [args]", "e <command> [args]"], "Execute a shell command and print the output", CmdCategory::General),
ChiselCommand::Clear => (&["clear", "c"], "Clear current session source", CmdCategory::Session),
ChiselCommand::Source => (&["source", "so"], "Display the source code of the current session", CmdCategory::Session),
ChiselCommand::Save => (&["save [id]", "s [id]"], "Save the current session to cache", CmdCategory::Session),
ChiselCommand::Load => (&["load <id>", "l <id>"], "Load a previous session ID from cache", CmdCategory::Session),
ChiselCommand::ListSessions => (&["list", "ls"], "List all cached sessions", CmdCategory::Session),
ChiselCommand::ClearCache => (&["clearcache", "cc"], "Clear the chisel cache of all stored sessions", CmdCategory::Session),
ChiselCommand::Export => (&["export", "ex"], "Export the current session source to a script file", CmdCategory::Session),
ChiselCommand::Fetch => (&["fetch <addr> <name>", "fe <addr> <name>"], "Fetch the interface of a verified contract on Etherscan", CmdCategory::Session),
ChiselCommand::Fork => (&["fork <url>", "f <url>"], "Fork an RPC for the current session. Supply 0 arguments to return to a local network", CmdCategory::Env),
ChiselCommand::Traces => (&["traces", "t"], "Enable / disable traces for the current session", CmdCategory::Env),
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),
ChiselCommand::MemDump => (&["memdump", "md"], "Dump the raw memory of the current state", CmdCategory::Debug),
ChiselCommand::StackDump => (&["stackdump", "sd"], "Dump the raw stack of the current state", CmdCategory::Debug),
ChiselCommand::Edit => (&["edit"], "Open the current session in an editor", CmdCategory::Session),
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),
}
}
}