#[macro_export] /// # JVCS_CLI Command Definition Macro /// /// ## Import /// /// Add the following macro to your code /// /// ```ignore /// crate::command_template!(); /// ``` /// /// Then paste the following content into your code /// /// ```ignore /// use std::any::TypeId; /// use cmd_system_macros::exec; /// use crate::{ /// cmd_output, /// systems::cmd::{ /// cmd_system::JVCommandContext, /// errors::{CmdExecuteError, CmdPrepareError}, /// workspace_reader::LocalWorkspaceReader, /// }, /// }; /// /// /// Define command type /// /// Names should match the file name in the following format: /// /// custom.rs matches JVCustomCommand, invoked using `jv custom ` /// /// get_data.rs matches JVGetDataCommand, invoked using `jv get data ` /// pub struct JVCustomCommand; /// /// /// Command type, should match the definition above /// type Cmd = JVCustomCommand; /// /// /// Specify Argument /// /// ```ignore /// /// #[derive(Parser, Debug)] /// /// pub struct JVCustomArgument; /// /// ``` /// type Arg = JVCustomArgument; /// /// /// Specify InputData /// /// ```ignore /// /// pub struct JVCustomInput; /// /// ``` /// type In = JVCustomInput; /// /// /// Specify CollectData /// /// ```ignore /// /// pub struct JVCustomCollect; /// /// ``` /// type Collect = JVCustomCollect; /// /// /// Return a string, rendered when the user needs help (command specifies `--help` or syntax error) /// fn help_str() -> String { /// todo!() /// } /// /// /// Preparation phase, preprocess user input and convert to a data format friendly for the execution phase /// async fn prepare(args: &Arg, ctx: &JVCommandContext) -> Result { /// todo!() /// } /// /// /// Collect necessary local information for execution /// async fn collect(args: &Arg, ctx: &JVCommandContext) -> Result { /// let reader = LocalWorkspaceReader::default(); /// todo!() /// } /// /// /// Execution phase, call core layer or other custom logic /// #[exec] /// async fn exec( /// input: In, /// collect: Collect, /// ) -> Result<(Box, TypeId), CmdExecuteError> { /// todo!(); /// /// // Use the following method to return results /// cmd_output!(JVCustomOutput => output) /// } /// ``` /// /// Of course, you can also use the comment-free version /// /// ```ignore /// use std::any::TypeId; /// use cmd_system_macros::exec; /// use crate::{ /// cmd_output, /// systems::cmd::{ /// cmd_system::JVCommandContext, /// errors::{CmdExecuteError, CmdPrepareError}, /// workspace_reader::LocalWorkspaceReader, /// }, /// }; /// /// pub struct JVCustomCommand; /// type Cmd = JVCustomCommand; /// type Arg = JVCustomArgument; /// type In = JVCustomInput; /// type Collect = JVCustomCollect; /// /// fn help_str() -> String { /// todo!() /// } /// /// async fn prepare(args: &Arg, ctx: &JVCommandContext) -> Result { /// todo!() /// } /// /// async fn collect(args: &Arg, ctx: &JVCommandContext) -> Result { /// let reader = LocalWorkspaceReader::default(); /// todo!() /// } /// /// #[exec] /// async fn exec( /// input: In, /// collect: Collect, /// ) -> Result<(Box, TypeId), CmdExecuteError> { /// todo!(); /// cmd_output!(JVCustomOutput => output) /// } /// ``` macro_rules! command_template { () => { impl $crate::systems::cmd::cmd_system::JVCommand for Cmd { fn get_help_str() -> String { help_str() } async fn prepare( args: &Arg, ctx: &$crate::systems::cmd::cmd_system::JVCommandContext, ) -> Result { prepare(args, ctx).await } async fn collect( args: &Arg, ctx: &$crate::systems::cmd::cmd_system::JVCommandContext, ) -> Result { collect(args, ctx).await } async fn exec( input: In, collect: Collect, ) -> Result< (Box, std::any::TypeId), $crate::systems::cmd::errors::CmdExecuteError, > { exec(input, collect).await } fn get_output_type_mapping() -> std::collections::HashMap { get_output_type_mapping() } } }; } #[macro_export] macro_rules! cmd_output { ($t:ty => $v:expr) => {{ let checked_value: $t = $v; Ok(( Box::new(checked_value) as Box, std::any::TypeId::of::<$t>(), )) }}; }