use crate::DEFAULT_KEY_COL_WIDTH;
use anyhow::{
Context,
Result,
};
use colored::Colorize as _;
use contract_build::{
util,
CrateMetadata,
};
use contract_transcode::ContractMessageTranscoder;
#[derive(Debug, Clone, clap::Args)]
#[clap(
name = "decode",
about = "Decodes the input or output data of a contract"
)]
pub struct DecodeCommand {
#[clap(value_enum, short, long)]
r#type: DataType,
#[clap(short, long)]
data: String,
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, clap::ValueEnum)]
enum DataType {
Event,
Message,
Constructor,
}
impl DecodeCommand {
pub fn run(&self) -> Result<()> {
let crate_metadata =
CrateMetadata::from_manifest_path(None, contract_build::Target::Wasm)?;
let transcoder = ContractMessageTranscoder::load(crate_metadata.metadata_path())?;
const ERR_MSG: &str = "Failed to decode specified data as a hex value";
let decoded_data = match self.r#type {
DataType::Event => {
transcoder.decode_contract_event(
&mut &util::decode_hex(&self.data).context(ERR_MSG)?[..],
)?
}
DataType::Message => {
transcoder.decode_contract_message(
&mut &util::decode_hex(&self.data).context(ERR_MSG)?[..],
)?
}
DataType::Constructor => {
transcoder.decode_contract_constructor(
&mut &util::decode_hex(&self.data).context(ERR_MSG)?[..],
)?
}
};
println!(
"{:>width$} {}",
"Decoded data:".bright_green().bold(),
decoded_data,
width = DEFAULT_KEY_COL_WIDTH
);
Ok(())
}
}