diff --git a/Cargo.lock b/Cargo.lock index 817e8b3..0e376f6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1599,18 +1599,18 @@ checksum = "b97ed7a9823b74f99c7742f5336af7be5ecd3eeafcb1507d1fa93347b1d589b0" [[package]] name = "serde" -version = "1.0.195" +version = "1.0.196" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63261df402c67811e9ac6def069e4786148c4563f4b50fd4bf30aa370d626b02" +checksum = "870026e60fa08c69f064aa766c10f10b1d62db9ccd4d0abb206472bee0ce3b32" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.195" +version = "1.0.196" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46fe8f8603d81ba86327b23a2e9cdf49e1255fb94a4c5f297f6ee0547178ea2c" +checksum = "33c85360c95e7d137454dc81d9a4ed2b8efd8fbe19cee57357b32b9771fccb67" dependencies = [ "proc-macro2", "quote", @@ -1763,6 +1763,7 @@ dependencies = [ "clap", "num", "prettytable", + "serde", "serde_json", "starknet", ] diff --git a/Cargo.toml b/Cargo.toml index 2f4ce1d..c9c5ee7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,7 +22,8 @@ doc = false anyhow = "1.0.79" camino = "1.1.6" clap = { version = "4.4.18", features = ["derive"] } +num = "0.4.1" prettytable = "0.10.0" starknet = { git = "https://github.com/xJonathanLEI/starknet-rs", rev = "c974e5cb42e8d8344cee910b76005ec46b4dd3ed" } +serde = "1.0.196" serde_json = { version = "1.0.99", features = ["preserve_order"] } -num = "0.4.1" diff --git a/src/bin/class_hash/commands/get.rs b/src/bin/class_hash/commands/get.rs index d3696fa..a14955c 100644 --- a/src/bin/class_hash/commands/get.rs +++ b/src/bin/class_hash/commands/get.rs @@ -1,3 +1,5 @@ +use std::collections::HashMap; + use anyhow::{Ok, Result}; use clap::Parser; use num::bigint::BigInt; @@ -7,16 +9,19 @@ use crate::commands::CliCommand; use class_hash::artifacts::get_artifacts; use class_hash::get_class_hashes; use class_hash::scarb::{clean, compile, get_scarb_manifest, print_compiler_versions}; +use class_hash::types::{Contract, Contracts}; #[derive(Parser, Debug)] pub struct Get { #[clap( - short, long, - default_value_t = true, - help = "Compile the project before computing the hashes" + action, + help = "Avoid compiling the project before computing the hashes" )] - pub compile: bool, + pub no_compile: bool, + + #[clap(long, action, help = "Outputs the class hashes in JSON format")] + pub json: bool, } impl CliCommand for Get { @@ -24,7 +29,7 @@ impl CliCommand for Get { fn run(&self) -> Result<()> { let _ = get_scarb_manifest()?; - if self.compile { + if !self.no_compile { clean()?; compile()?; } @@ -32,35 +37,77 @@ impl CliCommand for Get { let artifacts = get_artifacts()?; let class_hashes = get_class_hashes(artifacts)?; - println!(); - let mut table = Table::new(); - table.set_format(*format::consts::FORMAT_NO_LINESEP_WITH_TITLE); - table.set_titles(row![bFg->"Contract:", bFg->"Class hashes:"]); - - for (i, artifact) in class_hashes.iter().enumerate() { - if i > 0 { - table.add_empty_row(); - } - let name = artifact.0; - let hashes = artifact.1; - let sierra = if hashes.0.is_empty() { - "_".to_string() - } else { - format!("0x{:x}", hashes.0.parse::()?) - }; - let casm = if hashes.1.is_empty() { - "_".to_string() - } else { - format!("0x{:x}", hashes.1.parse::()?) - }; - table.add_row(row![bFy->name, format!("Sierra: {}", sierra)]); - table.add_row(row!["", format!("Casm: {}", casm)]); + if self.json { + print_json_output(class_hashes)?; + } else { + print_table_output(class_hashes)?; } - table.printstd(); - - println!(); - print_compiler_versions()?; Ok(()) } } + +/// Print the class hashes in JSON format. +fn print_json_output(class_hashes: HashMap) -> Result<()> { + println!(); + + let mut contracts = Contracts { + contracts: Vec::new(), + }; + + for artifact in class_hashes.iter() { + let name = artifact.0; + let hashes = artifact.1; + let sierra = if hashes.0.is_empty() { + "_".to_string() + } else { + format!("0x{:x}", hashes.0.parse::()?) + }; + let casm = if hashes.1.is_empty() { + "_".to_string() + } else { + format!("0x{:x}", hashes.1.parse::()?) + }; + contracts + .contracts + .push(Contract::new(name.to_string(), sierra, casm)); + } + + println!("{}", serde_json::to_string_pretty(&contracts)?); + + Ok(()) +} + +/// Print the class hashes in table format. +fn print_table_output(class_hashes: HashMap) -> Result<()> { + println!(); + let mut table = Table::new(); + table.set_format(*format::consts::FORMAT_NO_LINESEP_WITH_TITLE); + table.set_titles(row![bFg->"Contract:", bFg->"Class hashes:"]); + + for (i, artifact) in class_hashes.iter().enumerate() { + if i > 0 { + table.add_empty_row(); + } + let name = artifact.0; + let hashes = artifact.1; + let sierra = if hashes.0.is_empty() { + "_".to_string() + } else { + format!("0x{:x}", hashes.0.parse::()?) + }; + let casm = if hashes.1.is_empty() { + "_".to_string() + } else { + format!("0x{:x}", hashes.1.parse::()?) + }; + table.add_row(row![bFy->name, format!("Sierra: {}", sierra)]); + table.add_row(row!["", format!("Casm: {}", casm)]); + } + table.printstd(); + + println!(); + print_compiler_versions()?; + + Ok(()) +} diff --git a/src/class_hash/lib.rs b/src/class_hash/lib.rs index af66036..bb08fbd 100644 --- a/src/class_hash/lib.rs +++ b/src/class_hash/lib.rs @@ -1,5 +1,6 @@ pub mod artifacts; pub mod scarb; +pub mod types; use anyhow::{Ok, Result}; use artifacts::Artifacts; diff --git a/src/class_hash/types.rs b/src/class_hash/types.rs new file mode 100644 index 0000000..83aa943 --- /dev/null +++ b/src/class_hash/types.rs @@ -0,0 +1,19 @@ +use serde::Serialize; + +#[derive(Serialize)] +pub struct Contract { + name: String, + sierra: String, + casm: String, +} + +#[derive(Serialize)] +pub struct Contracts { + pub contracts: Vec, +} + +impl Contract { + pub fn new(name: String, sierra: String, casm: String) -> Self { + Self { name, sierra, casm } + } +}