use clap::Parser; use sov_modules_api::cli::JsonStringArg; use sov_modules_api::default_context::DefaultContext; use sov_modules_api::macros::{CliWallet, CliWalletArg, DefaultRuntime}; use sov_modules_api::{ CallResponse, Context, DispatchCall, Error, Genesis, MessageCodec, Module, ModuleInfo, StateValue, WorkingSet }; pub mod first_test_module { use super::*; #[derive( CliWalletArg, Debug, PartialEq, borsh::BorshDeserialize, borsh::BorshSerialize, serde::Serialize, serde::Deserialize, )] pub struct MyStruct { pub first_field: u32, pub str_field: String, } #[derive(ModuleInfo)] pub struct FirstTestStruct { #[address] pub address: C::Address, #[state] pub state_in_first_struct: StateValue, } impl Module for FirstTestStruct { type Context = C; type Config = (); type CallMessage = MyStruct; fn genesis( &self, _config: &Self::Config, _working_set: &mut WorkingSet, ) -> Result<(), Error> { Ok(()) } fn call( &self, _msg: Self::CallMessage, _context: &Self::Context, _working_set: &mut WorkingSet, ) -> Result { Ok(CallResponse::default()) } } } pub mod second_test_module { use super::*; #[derive(ModuleInfo)] pub struct SecondTestStruct { #[address] pub address: Ctx::Address, #[state] pub state_in_second_struct: StateValue, } #[derive( CliWalletArg, Debug, PartialEq, borsh::BorshDeserialize, borsh::BorshSerialize, serde::Serialize, serde::Deserialize, )] pub enum MyEnum { Foo { first_field: u32, str_field: String }, Bar(u8), } impl Module for SecondTestStruct { type Context = Ctx; type Config = (); type CallMessage = MyEnum; fn genesis( &self, _config: &Self::Config, _working_set: &mut WorkingSet, ) -> Result<(), Error> { Ok(()) } fn call( &self, _msg: Self::CallMessage, _context: &Self::Context, _working_set: &mut WorkingSet, ) -> Result { Ok(CallResponse::default()) } } } #[derive(Genesis, DispatchCall, MessageCodec, DefaultRuntime, CliWallet)] #[serialization(borsh::BorshDeserialize, borsh::BorshSerialize)] pub struct Runtime { pub first: first_test_module::FirstTestStruct, pub second: second_test_module::SecondTestStruct, } fn main() { let expected_foo = RuntimeCall::first(first_test_module::MyStruct { first_field: 1, str_field: "hello".to_string(), }); let foo_from_cli: RuntimeSubcommand = >::try_parse_from(&[ "main", "first", "--json", r#"{"first_field": 1, "str_field": "hello"}"#, ]) .expect("parsing must succed") .into(); let foo_ir: RuntimeMessage = foo_from_cli.try_into().unwrap(); assert_eq!(expected_foo, foo_ir.try_into().unwrap()); let expected_bar = RuntimeCall::second(second_test_module::MyEnum::Bar(2)); let bar_from_cli: RuntimeSubcommand = >::try_parse_from(&[ "main", "second", "--json", r#"{"Bar": 2}"#, ]) .expect("parsing must succed") .into(); let bar_ir: RuntimeMessage = bar_from_cli.try_into().unwrap(); assert_eq!(expected_bar, bar_ir.try_into().unwrap()); }