mirror of
https://github.com/Start9Labs/rpc-toolkit.git
synced 2026-03-26 02:11:56 +00:00
custom_cli
This commit is contained in:
@@ -493,7 +493,14 @@ fn rpc_handler(
|
||||
method: &str,
|
||||
args: Params#param_ty_generics,
|
||||
) -> Result<::rpc_toolkit::command_helpers::prelude::Value, ::rpc_toolkit::command_helpers::prelude::RpcError> {
|
||||
Ok(::rpc_toolkit::command_helpers::prelude::to_value(#invocation)?)
|
||||
if method.is_empty() {
|
||||
Ok(::rpc_toolkit::command_helpers::prelude::to_value(#invocation)?)
|
||||
} else {
|
||||
Err(::rpc_toolkit::command_helpers::prelude::RpcError {
|
||||
data: Some(method.into()),
|
||||
..::rpc_toolkit::command_helpers::prelude::yajrc::METHOD_NOT_FOUND_ERROR
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -818,44 +825,91 @@ fn cli_handler(
|
||||
}
|
||||
}
|
||||
Options::Leaf(opt) => {
|
||||
let invocation = if opt.is_async {
|
||||
if let ExecutionContext::CustomCli {
|
||||
ref cli, is_async, ..
|
||||
} = opt.exec_ctx
|
||||
{
|
||||
let fn_path = cli;
|
||||
let invocation = if is_async {
|
||||
quote! {
|
||||
rt_ref.block_on(#fn_path(#(#param),*))?
|
||||
}
|
||||
} else {
|
||||
quote! {
|
||||
#fn_path(#(#param),*)?
|
||||
}
|
||||
};
|
||||
let display_res = if let Some(display_fn) = &opt.display {
|
||||
quote! {
|
||||
#display_fn(#invocation, matches)
|
||||
}
|
||||
} else {
|
||||
quote! {
|
||||
::rpc_toolkit::command_helpers::prelude::default_display(#invocation, matches)
|
||||
}
|
||||
};
|
||||
let rt_action = if is_async {
|
||||
create_rt
|
||||
} else {
|
||||
quote! {
|
||||
drop(rt);
|
||||
}
|
||||
};
|
||||
quote! {
|
||||
rt_ref.block_on(#fn_path(#(#param),*))?
|
||||
}
|
||||
} else {
|
||||
quote! {
|
||||
#fn_path(#(#param),*)?
|
||||
}
|
||||
};
|
||||
let display_res = if let Some(display_fn) = &opt.display {
|
||||
quote! {
|
||||
#display_fn(#invocation, matches)
|
||||
}
|
||||
} else {
|
||||
quote! {
|
||||
::rpc_toolkit::command_helpers::prelude::default_display(#invocation, matches)
|
||||
}
|
||||
};
|
||||
let rt_action = if opt.is_async {
|
||||
create_rt
|
||||
} else {
|
||||
quote! {
|
||||
drop(rt);
|
||||
}
|
||||
};
|
||||
quote! {
|
||||
pub fn cli_handler#generics(
|
||||
ctx: #ctx_ty,
|
||||
mut rt: Option<::rpc_toolkit::command_helpers::prelude::Runtime>,
|
||||
matches: &::rpc_toolkit::command_helpers::prelude::ArgMatches<'_>,
|
||||
_method: ::rpc_toolkit::command_helpers::prelude::Cow<'_, str>,
|
||||
parent_params: ParentParams
|
||||
) -> Result<(), ::rpc_toolkit::command_helpers::prelude::RpcError> {
|
||||
#param_struct_def
|
||||
pub fn cli_handler#generics(
|
||||
ctx: #ctx_ty,
|
||||
mut rt: Option<::rpc_toolkit::command_helpers::prelude::Runtime>,
|
||||
matches: &::rpc_toolkit::command_helpers::prelude::ArgMatches<'_>,
|
||||
_method: ::rpc_toolkit::command_helpers::prelude::Cow<'_, str>,
|
||||
parent_params: ParentParams
|
||||
) -> Result<(), ::rpc_toolkit::command_helpers::prelude::RpcError> {
|
||||
#param_struct_def
|
||||
|
||||
#rt_action
|
||||
#rt_action
|
||||
|
||||
Ok(#display_res)
|
||||
Ok(#display_res)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
let invocation = if opt.is_async {
|
||||
quote! {
|
||||
rt_ref.block_on(#fn_path(#(#param),*))?
|
||||
}
|
||||
} else {
|
||||
quote! {
|
||||
#fn_path(#(#param),*)?
|
||||
}
|
||||
};
|
||||
let display_res = if let Some(display_fn) = &opt.display {
|
||||
quote! {
|
||||
#display_fn(#invocation, matches)
|
||||
}
|
||||
} else {
|
||||
quote! {
|
||||
::rpc_toolkit::command_helpers::prelude::default_display(#invocation, matches)
|
||||
}
|
||||
};
|
||||
let rt_action = if opt.is_async {
|
||||
create_rt
|
||||
} else {
|
||||
quote! {
|
||||
drop(rt);
|
||||
}
|
||||
};
|
||||
quote! {
|
||||
pub fn cli_handler#generics(
|
||||
ctx: #ctx_ty,
|
||||
mut rt: Option<::rpc_toolkit::command_helpers::prelude::Runtime>,
|
||||
matches: &::rpc_toolkit::command_helpers::prelude::ArgMatches<'_>,
|
||||
_method: ::rpc_toolkit::command_helpers::prelude::Cow<'_, str>,
|
||||
parent_params: ParentParams
|
||||
) -> Result<(), ::rpc_toolkit::command_helpers::prelude::RpcError> {
|
||||
#param_struct_def
|
||||
|
||||
#rt_action
|
||||
|
||||
Ok(#display_res)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,11 @@ pub enum ExecutionContext {
|
||||
CliOnly(Path),
|
||||
RpcOnly(Path),
|
||||
Local(Path),
|
||||
CustomCli {
|
||||
custom: Path,
|
||||
cli: Path,
|
||||
is_async: bool,
|
||||
},
|
||||
}
|
||||
impl Default for ExecutionContext {
|
||||
fn default() -> Self {
|
||||
|
||||
@@ -126,6 +126,73 @@ pub fn parse_command_attr(args: AttributeArgs) -> Result<Options> {
|
||||
"`display` cannot be assigned to",
|
||||
));
|
||||
}
|
||||
NestedMeta::Meta(Meta::List(list)) if list.path.is_ident("custom_cli") => {
|
||||
if list.nested.len() == 1 {
|
||||
match &opt.common().exec_ctx {
|
||||
ExecutionContext::Standard => match &list.nested[0] {
|
||||
NestedMeta::Meta(Meta::Path(custom_cli_impl)) => {
|
||||
opt.common().exec_ctx = ExecutionContext::CustomCli {
|
||||
custom: list.path,
|
||||
cli: custom_cli_impl.clone(),
|
||||
is_async: false,
|
||||
}
|
||||
}
|
||||
NestedMeta::Meta(Meta::List(custom_cli_impl)) if custom_cli_impl.nested.len() == 1 => {
|
||||
let is_async = match custom_cli_impl.nested.first().unwrap() {
|
||||
NestedMeta::Meta(Meta::Path(p)) if p.is_ident("async") => false,
|
||||
arg => return Err(Error::new(arg.span(), "unknown argument")),
|
||||
};
|
||||
opt.common().exec_ctx = ExecutionContext::CustomCli {
|
||||
custom: list.path,
|
||||
cli: custom_cli_impl.path.clone(),
|
||||
is_async,
|
||||
};
|
||||
}
|
||||
a => {
|
||||
return Err(Error::new(
|
||||
a.span(),
|
||||
"`custom_cli` implementation must be a path, or a list with 1 argument",
|
||||
))
|
||||
}
|
||||
},
|
||||
ExecutionContext::CliOnly(_) => {
|
||||
return Err(Error::new(list.span(), "duplicate argument: `cli_only`"))
|
||||
}
|
||||
ExecutionContext::RpcOnly(_) => {
|
||||
return Err(Error::new(
|
||||
list.span(),
|
||||
"`cli_only` and `rpc_only` are mutually exclusive",
|
||||
))
|
||||
}
|
||||
ExecutionContext::Local(_) => {
|
||||
return Err(Error::new(
|
||||
list.span(),
|
||||
"`cli_only` and `local` are mutually exclusive",
|
||||
))
|
||||
}
|
||||
ExecutionContext::CustomCli { .. } => {
|
||||
return Err(Error::new(
|
||||
list.span(),
|
||||
"`cli_only` and `custom_cli` are mutually exclusive",
|
||||
))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return Err(Error::new(
|
||||
list.nested.span(),
|
||||
"`custom_cli` can only have one implementation",
|
||||
));
|
||||
}
|
||||
}
|
||||
NestedMeta::Meta(Meta::Path(p)) if p.is_ident("custom_cli") => {
|
||||
return Err(Error::new(p.span(), "`custom_cli` requires an argument"));
|
||||
}
|
||||
NestedMeta::Meta(Meta::NameValue(nv)) if nv.path.is_ident("custom_cli") => {
|
||||
return Err(Error::new(
|
||||
nv.path.span(),
|
||||
"`custom_cli` cannot be assigned to",
|
||||
));
|
||||
}
|
||||
NestedMeta::Meta(Meta::List(list)) if list.path.is_ident("aliases") => {
|
||||
if !opt.common().aliases.is_empty() {
|
||||
return Err(Error::new(list.span(), "duplicate argument `alias`"));
|
||||
@@ -170,6 +237,12 @@ pub fn parse_command_attr(args: AttributeArgs) -> Result<Options> {
|
||||
"`cli_only` and `local` are mutually exclusive",
|
||||
))
|
||||
}
|
||||
ExecutionContext::CustomCli { .. } => {
|
||||
return Err(Error::new(
|
||||
p.span(),
|
||||
"`cli_only` and `custom_cli` are mutually exclusive",
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
NestedMeta::Meta(Meta::List(list)) if list.path.is_ident("cli_only") => {
|
||||
@@ -204,6 +277,12 @@ pub fn parse_command_attr(args: AttributeArgs) -> Result<Options> {
|
||||
"`rpc_only` and `local` are mutually exclusive",
|
||||
))
|
||||
}
|
||||
ExecutionContext::CustomCli { .. } => {
|
||||
return Err(Error::new(
|
||||
p.span(),
|
||||
"`rpc_only` and `custom_cli` are mutually exclusive",
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
NestedMeta::Meta(Meta::List(list)) if list.path.is_ident("rpc_only") => {
|
||||
@@ -238,6 +317,12 @@ pub fn parse_command_attr(args: AttributeArgs) -> Result<Options> {
|
||||
"`local` and `cli_only` are mutually exclusive",
|
||||
))
|
||||
}
|
||||
ExecutionContext::CustomCli { .. } => {
|
||||
return Err(Error::new(
|
||||
p.span(),
|
||||
"`local` and `custom_cli` are mutually exclusive",
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
NestedMeta::Meta(Meta::List(list)) if list.path.is_ident("local") => {
|
||||
|
||||
Reference in New Issue
Block a user