diff --git a/crates/sncast/src/response/account/create.rs b/crates/sncast/src/response/account/create.rs index 33aca415f6..48c2db9742 100644 --- a/crates/sncast/src/response/account/create.rs +++ b/crates/sncast/src/response/account/create.rs @@ -9,7 +9,6 @@ use foundry_ui::Message; use foundry_ui::styling; use serde::{Serialize, Serializer}; use serde_json::Value; -use serde_json::json; fn as_str(value: &u128, serializer: S) -> Result where @@ -48,13 +47,7 @@ impl Message for SncastMessage { } fn json(&self) -> Value { - serde_json::to_value(&self.command_response).unwrap_or_else(|err| { - json!({ - "error": "Failed to serialize response", - "command": self.command, - "details": err.to_string() - }) - }) + self.to_json() } } diff --git a/crates/sncast/src/response/account/delete.rs b/crates/sncast/src/response/account/delete.rs index 18f829a3e2..c1c53d94bb 100644 --- a/crates/sncast/src/response/account/delete.rs +++ b/crates/sncast/src/response/account/delete.rs @@ -4,7 +4,6 @@ use foundry_ui::Message; use foundry_ui::styling; use serde::Serialize; use serde_json::Value; -use serde_json::json; #[derive(Serialize, Clone)] pub struct AccountDeleteResponse { @@ -23,12 +22,6 @@ impl Message for SncastMessage { } fn json(&self) -> Value { - serde_json::to_value(&self.command_response).unwrap_or_else(|err| { - json!({ - "error": "Failed to serialize response", - "command": self.command, - "details": err.to_string() - }) - }) + self.to_json() } } diff --git a/crates/sncast/src/response/account/deploy.rs b/crates/sncast/src/response/account/deploy.rs index 19b0b55098..33ba8c9ce9 100644 --- a/crates/sncast/src/response/account/deploy.rs +++ b/crates/sncast/src/response/account/deploy.rs @@ -9,7 +9,6 @@ use foundry_ui::Message; use foundry_ui::styling; use serde::{Deserialize, Serialize}; use serde_json::Value; -use serde_json::json; #[derive(Serialize, Deserialize, CairoSerialize, Clone, Debug, PartialEq)] pub struct AccountDeployResponse { pub transaction_hash: PaddedFelt, @@ -37,13 +36,7 @@ impl Message for SncastMessage { } fn json(&self) -> Value { - serde_json::to_value(&self.command_response).unwrap_or_else(|err| { - json!({ - "error": "Failed to serialize response", - "command": self.command, - "details": err.to_string() - }) - }) + self.to_json() } } diff --git a/crates/sncast/src/response/account/import.rs b/crates/sncast/src/response/account/import.rs index bf03f35cca..1021473f78 100644 --- a/crates/sncast/src/response/account/import.rs +++ b/crates/sncast/src/response/account/import.rs @@ -4,7 +4,6 @@ use foundry_ui::Message; use foundry_ui::styling; use serde::Serialize; use serde_json::Value; -use serde_json::json; #[derive(Serialize, Clone)] pub struct AccountImportResponse { @@ -28,12 +27,6 @@ impl Message for SncastMessage { } fn json(&self) -> Value { - serde_json::to_value(&self.command_response).unwrap_or_else(|err| { - json!({ - "error": "Failed to serialize response", - "command": self.command, - "details": err.to_string() - }) - }) + self.to_json() } } diff --git a/crates/sncast/src/response/call.rs b/crates/sncast/src/response/call.rs index 35f04c86d7..8fca9b8ab0 100644 --- a/crates/sncast/src/response/call.rs +++ b/crates/sncast/src/response/call.rs @@ -6,7 +6,6 @@ use foundry_ui::Message; use foundry_ui::styling; use serde::Serialize; use serde_json::Value; -use serde_json::json; use starknet_types_core::felt::Felt; #[derive(Serialize, CairoSerialize, Clone)] @@ -34,12 +33,6 @@ impl Message for SncastMessage { } fn json(&self) -> Value { - serde_json::to_value(&self.command_response).unwrap_or_else(|err| { - json!({ - "error": "Failed to serialize response", - "command": self.command, - "details": err.to_string() - }) - }) + self.to_json() } } diff --git a/crates/sncast/src/response/cast_message.rs b/crates/sncast/src/response/cast_message.rs index fc47e585ed..d6703cde0c 100644 --- a/crates/sncast/src/response/cast_message.rs +++ b/crates/sncast/src/response/cast_message.rs @@ -6,3 +6,31 @@ pub struct SncastMessage { pub command: String, pub command_response: T, } + +impl SncastMessage { + pub fn to_json(&self) -> serde_json::Value { + match serde_json::to_value(&self.command_response) { + Ok(serde_json::Value::Object(mut map)) => { + map.insert( + "command".to_string(), + serde_json::Value::String(self.command.clone()), + ); + serde_json::Value::Object(map) + } + Ok(other) => { + serde_json::json!({ + "error": "Expected a map for `command_response`", + "command": self.command, + "details": other.to_string() + }) + } + Err(err) => { + serde_json::json!({ + "error": "Failed to serialize response", + "command": self.command, + "details": err.to_string() + }) + } + } + } +} diff --git a/crates/sncast/src/response/declare.rs b/crates/sncast/src/response/declare.rs index b4f77b2faf..2a4da1cbfa 100644 --- a/crates/sncast/src/response/declare.rs +++ b/crates/sncast/src/response/declare.rs @@ -8,7 +8,6 @@ use foundry_ui::styling; use indoc::formatdoc; use serde::{Deserialize, Serialize}; use serde_json::Value; -use serde_json::json; #[derive(Clone, Serialize, Deserialize, CairoSerialize, Debug, PartialEq)] pub struct DeclareTransactionResponse { pub class_hash: PaddedFelt, @@ -34,13 +33,7 @@ impl Message for SncastMessage { } fn json(&self) -> Value { - serde_json::to_value(&self.command_response).unwrap_or_else(|err| { - json!({ - "error": "Failed to serialize response", - "command": self.command, - "details": err.to_string() - }) - }) + self.to_json() } } @@ -64,13 +57,7 @@ impl Message for SncastMessage { } fn json(&self) -> Value { - serde_json::to_value(&self.command_response).unwrap_or_else(|err| { - json!({ - "error": "Failed to serialize response", - "command": self.command, - "details": err.to_string() - }) - }) + self.to_json() } } @@ -105,13 +92,7 @@ impl Message for SncastMessage { } fn json(&self) -> Value { - serde_json::to_value(&self.command_response).unwrap_or_else(|err| { - json!({ - "error": "Failed to serialize response", - "command": self.command, - "details": err.to_string() - }) - }) + self.to_json() } } diff --git a/crates/sncast/src/response/deploy.rs b/crates/sncast/src/response/deploy.rs index eebddedbe5..3258e39a53 100644 --- a/crates/sncast/src/response/deploy.rs +++ b/crates/sncast/src/response/deploy.rs @@ -6,7 +6,6 @@ use foundry_ui::styling; use indoc::formatdoc; use serde::{Deserialize, Serialize}; use serde_json::Value; -use serde_json::json; use super::{command::CommandResponse, explorer_link::OutputLink}; use crate::response::cast_message::SncastMessage; @@ -36,13 +35,7 @@ impl Message for SncastMessage { } fn json(&self) -> Value { - serde_json::to_value(&self.command_response).unwrap_or_else(|err| { - json!({ - "error": "Failed to serialize response", - "command": self.command, - "details": err.to_string() - }) - }) + self.to_json() } } diff --git a/crates/sncast/src/response/invoke.rs b/crates/sncast/src/response/invoke.rs index c93a408bb3..06d2088474 100644 --- a/crates/sncast/src/response/invoke.rs +++ b/crates/sncast/src/response/invoke.rs @@ -8,7 +8,6 @@ use foundry_ui::Message; use foundry_ui::styling; use serde::{Deserialize, Serialize}; use serde_json::Value; -use serde_json::json; #[derive(Serialize, Deserialize, CairoSerialize, Clone, Debug, PartialEq)] pub struct InvokeResponse { @@ -30,13 +29,7 @@ impl Message for SncastMessage { } fn json(&self) -> Value { - serde_json::to_value(&self.command_response).unwrap_or_else(|err| { - json!({ - "error": "Failed to serialize response", - "command": self.command, - "details": err.to_string() - }) - }) + self.to_json() } } diff --git a/crates/sncast/src/response/multicall/new.rs b/crates/sncast/src/response/multicall/new.rs index 968cab2351..cfd141863a 100644 --- a/crates/sncast/src/response/multicall/new.rs +++ b/crates/sncast/src/response/multicall/new.rs @@ -5,7 +5,6 @@ use foundry_ui::Message; use foundry_ui::styling; use serde::Serialize; use serde_json::Value; -use serde_json::json; #[derive(Serialize, Clone)] pub struct MulticallNewResponse { @@ -26,12 +25,6 @@ impl Message for SncastMessage { } fn json(&self) -> Value { - serde_json::to_value(&self.command_response).unwrap_or_else(|err| { - json!({ - "error": "Failed to serialize response", - "command": self.command, - "details": err.to_string() - }) - }) + self.to_json() } } diff --git a/crates/sncast/src/response/multicall/run.rs b/crates/sncast/src/response/multicall/run.rs index 9963f0ab45..b7b458d1e8 100644 --- a/crates/sncast/src/response/multicall/run.rs +++ b/crates/sncast/src/response/multicall/run.rs @@ -11,7 +11,6 @@ use foundry_ui::Message; use foundry_ui::styling; use serde::{Deserialize, Serialize}; use serde_json::Value; -use serde_json::json; #[derive(Serialize, Deserialize, CairoSerialize, Clone, Debug, PartialEq)] pub struct MulticallRunResponse { @@ -33,13 +32,7 @@ impl Message for SncastMessage { } fn json(&self) -> Value { - serde_json::to_value(&self.command_response).unwrap_or_else(|err| { - json!({ - "error": "Failed to serialize response", - "command": self.command, - "details": err.to_string() - }) - }) + self.to_json() } } diff --git a/crates/sncast/src/response/script/init.rs b/crates/sncast/src/response/script/init.rs index d2cbfe15fb..5e16919d16 100644 --- a/crates/sncast/src/response/script/init.rs +++ b/crates/sncast/src/response/script/init.rs @@ -4,7 +4,6 @@ use foundry_ui::Message; use foundry_ui::styling; use serde::Serialize; use serde_json::Value; -use serde_json::json; #[derive(Serialize, Clone)] pub struct ScriptInitResponse { @@ -23,12 +22,6 @@ impl Message for SncastMessage { } fn json(&self) -> Value { - serde_json::to_value(&self.command_response).unwrap_or_else(|err| { - json!({ - "error": "Failed to serialize response", - "command": self.command, - "details": err.to_string() - }) - }) + self.to_json() } } diff --git a/crates/sncast/src/response/script/run.rs b/crates/sncast/src/response/script/run.rs index 1b67768838..847e8273ec 100644 --- a/crates/sncast/src/response/script/run.rs +++ b/crates/sncast/src/response/script/run.rs @@ -4,7 +4,6 @@ use foundry_ui::Message; use foundry_ui::styling; use serde::Serialize; use serde_json::Value; -use serde_json::json; #[derive(Serialize, Debug, Clone)] pub struct ScriptRunResponse { @@ -29,12 +28,6 @@ impl Message for SncastMessage { } fn json(&self) -> Value { - serde_json::to_value(&self.command_response).unwrap_or_else(|err| { - json!({ - "error": "Failed to serialize response", - "command": self.command, - "details": err.to_string() - }) - }) + self.to_json() } } diff --git a/crates/sncast/src/response/serialize.rs b/crates/sncast/src/response/serialize.rs index 47bb56afa2..23d26c7cae 100644 --- a/crates/sncast/src/response/serialize.rs +++ b/crates/sncast/src/response/serialize.rs @@ -5,7 +5,6 @@ use foundry_ui::Message; use foundry_ui::styling; use serde::{Deserialize, Serialize}; use serde_json::Value; -use serde_json::json; use starknet_types_core::felt::Felt; #[derive(Serialize, Deserialize, CairoSerialize, Clone, Debug, PartialEq)] @@ -25,12 +24,6 @@ impl Message for SncastMessage { } fn json(&self) -> Value { - serde_json::to_value(&self.command_response).unwrap_or_else(|err| { - json!({ - "error": "Failed to serialize response", - "command": self.command, - "details": err.to_string() - }) - }) + self.to_json() } } diff --git a/crates/sncast/src/response/show_config.rs b/crates/sncast/src/response/show_config.rs index fb3a248866..4a72cd4c12 100644 --- a/crates/sncast/src/response/show_config.rs +++ b/crates/sncast/src/response/show_config.rs @@ -4,7 +4,6 @@ use foundry_ui::Message; use foundry_ui::styling; use serde::Serialize; use serde_json::Value; -use serde_json::json; use super::command::CommandResponse; use crate::response::cast_message::SncastMessage; @@ -67,12 +66,6 @@ impl Message for SncastMessage { } fn json(&self) -> Value { - serde_json::to_value(&self.command_response).unwrap_or_else(|err| { - json!({ - "error": "Failed to serialize response", - "command": self.command, - "details": err.to_string() - }) - }) + self.to_json() } } diff --git a/crates/sncast/src/response/transformed_call.rs b/crates/sncast/src/response/transformed_call.rs index f55a6184b2..0be0db8f15 100644 --- a/crates/sncast/src/response/transformed_call.rs +++ b/crates/sncast/src/response/transformed_call.rs @@ -8,7 +8,6 @@ use foundry_ui::Message; use foundry_ui::styling; use serde::Serialize; use serde_json::Value; -use serde_json::json; use starknet::core::types::{ContractClass, contract::AbiEntry}; use starknet_types_core::felt::Felt; @@ -39,13 +38,7 @@ impl Message for SncastMessage { } fn json(&self) -> Value { - serde_json::to_value(&self.command_response).unwrap_or_else(|err| { - json!({ - "error": "Failed to serialize response", - "command": self.command, - "details": err.to_string() - }) - }) + self.to_json() } } diff --git a/crates/sncast/src/response/tx_status.rs b/crates/sncast/src/response/tx_status.rs index 1274fa655b..67af468a66 100644 --- a/crates/sncast/src/response/tx_status.rs +++ b/crates/sncast/src/response/tx_status.rs @@ -5,7 +5,6 @@ use foundry_ui::Message; use foundry_ui::styling; use serde::Serialize; use serde_json::Value; -use serde_json::json; #[derive(Serialize, CairoSerialize, Clone)] pub enum FinalityStatus { @@ -57,12 +56,6 @@ impl Message for SncastMessage { } fn json(&self) -> Value { - serde_json::to_value(&self.command_response).unwrap_or_else(|err| { - json!({ - "error": "Failed to serialize response", - "command": self.command, - "details": err.to_string() - }) - }) + self.to_json() } } diff --git a/crates/sncast/src/response/verify.rs b/crates/sncast/src/response/verify.rs index dd87adb913..8f4e23143b 100644 --- a/crates/sncast/src/response/verify.rs +++ b/crates/sncast/src/response/verify.rs @@ -2,7 +2,6 @@ use foundry_ui::Message; use foundry_ui::styling; use serde::Serialize; use serde_json::Value; -use serde_json::json; use super::command::CommandResponse; use crate::response::cast_message::SncastMessage; @@ -24,12 +23,6 @@ impl Message for SncastMessage { } fn json(&self) -> Value { - serde_json::to_value(&self.command_response).unwrap_or_else(|err| { - json!({ - "error": "Failed to serialize response", - "command": self.command, - "details": err.to_string() - }) - }) + self.to_json() } } diff --git a/crates/sncast/src/starknet_commands/utils/mod.rs b/crates/sncast/src/starknet_commands/utils/mod.rs index 69c32a7cfb..9e9c35511d 100644 --- a/crates/sncast/src/starknet_commands/utils/mod.rs +++ b/crates/sncast/src/starknet_commands/utils/mod.rs @@ -50,7 +50,7 @@ pub async fn utils( .await .map_err(handle_starknet_command_error)?; - process_command_result("serialize", Ok(result), ui, None); + process_command_result("utils serialize", Ok(result), ui, None); } Commands::ClassHash(class_hash) => { diff --git a/crates/sncast/tests/e2e/account/create.rs b/crates/sncast/tests/e2e/account/create.rs index af135dd365..46d5688464 100644 --- a/crates/sncast/tests/e2e/account/create.rs +++ b/crates/sncast/tests/e2e/account/create.rs @@ -1011,7 +1011,7 @@ pub async fn test_json_output_format() { .env("SNCAST_FORCE_SHOW_EXPLORER_LINKS", "1") .current_dir(temp_dir.path()); snapbox.assert().stdout_matches(indoc! {r#" - {"add_profile":"Profile my_account successfully added to [..]/snfoundry.toml","address":"0x[..]","estimated_fee":"[..]","message":"Account successfully created but it needs to be deployed. The estimated deployment fee is [..] STRK. Prefund the account to cover deployment transaction fee/n/nAfter prefunding the account, run:/nsncast --accounts-file accounts.json account deploy --url [..] --name my_account"} + {"command":"account create","add_profile":"Profile my_account successfully added to [..]/snfoundry.toml","address":"0x[..]","estimated_fee":"[..]","message":"Account successfully created but it needs to be deployed. The estimated deployment fee is [..] STRK. Prefund the account to cover deployment transaction fee/n/nAfter prefunding the account, run:/nsncast --accounts-file accounts.json account deploy --url [..] --name my_account"} {"links":"account: https://sepolia.starkscan.co/contract/0x[..]","title":"account creation"} "#}); } diff --git a/crates/sncast/tests/e2e/account/deploy.rs b/crates/sncast/tests/e2e/account/deploy.rs index 1e3938665c..bd5aaa4cae 100644 --- a/crates/sncast/tests/e2e/account/deploy.rs +++ b/crates/sncast/tests/e2e/account/deploy.rs @@ -609,6 +609,6 @@ pub async fn test_json_output_format() { .current_dir(tempdir.path()); snapbox.assert().stdout_matches(indoc! {r#" {"transaction_hash":"0x0[..]"} - {"links":"transaction: https://sepolia.starkscan.co/tx/0x0[..]","title":"account deployment"} + {"command":"account deploy","links":"transaction: https://sepolia.starkscan.co/tx/0x0[..]","title":"account deployment"} "#}); } diff --git a/crates/sncast/tests/e2e/call.rs b/crates/sncast/tests/e2e/call.rs index ac00a442e9..615273da08 100644 --- a/crates/sncast/tests/e2e/call.rs +++ b/crates/sncast/tests/e2e/call.rs @@ -290,6 +290,6 @@ fn test_json_output_format() { let snapbox = runner(&args); snapbox.assert().success().stdout_eq(indoc! {r#" - {"response":"0x0","response_raw":["0x0"]} + {"command":"call","response":"0x0","response_raw":["0x0"]} "#}); } diff --git a/crates/sncast/tests/e2e/deploy.rs b/crates/sncast/tests/e2e/deploy.rs index 76cb451d15..593a560929 100644 --- a/crates/sncast/tests/e2e/deploy.rs +++ b/crates/sncast/tests/e2e/deploy.rs @@ -400,7 +400,7 @@ async fn test_json_output_format() { assert_stdout_contains( output, indoc! {r#" - {"contract_address":"0x[..]","transaction_hash":"0x[..]"} + {"command":"deploy","contract_address":"0x[..]","transaction_hash":"0x[..]"} {"links":"contract: https://sepolia.starkscan.co/contract/0x[..]\ntransaction: https://sepolia.starkscan.co/tx/0x[..]\n","title":"deployment"} "#}, ); diff --git a/crates/sncast/tests/e2e/serialize.rs b/crates/sncast/tests/e2e/serialize.rs index 525817152f..300e017c99 100644 --- a/crates/sncast/tests/e2e/serialize.rs +++ b/crates/sncast/tests/e2e/serialize.rs @@ -178,7 +178,7 @@ async fn test_happy_case_json() { let snapbox = runner(&args).current_dir(tempdir.path()); snapbox.assert().success().stdout_eq(indoc! {r#" - {"calldata":["0x24","0x60"]} + {"command":"utils serialize","calldata":["0x24","0x60"]} "#}); }