nushell/src/commands/macros.rs

353 lines
11 KiB
Rust
Raw Normal View History

2019-07-15 23:16:27 +02:00
#[doc(hidden)]
#[macro_export]
macro_rules! command {
(
Named { $export:tt $args:ident $body:block }
Positional { $($number:tt)* }
Rest {}
2019-08-02 21:15:07 +02:00
Signature {
name: $config_name:tt,
mandatory_positional: vec![ $($mandatory_positional:tt)* ],
optional_positional: vec![ $($optional_positional:tt)* ],
rest_positional: $rest_positional:tt,
named: {
$(
2019-07-15 23:16:27 +02:00
($named_param:tt : $named_type:ty : $named_kind:tt)
)*
}
}
Function {
$( ( $param_name:tt : $param_type:tt ) )*
}
Extract {
$($extract:tt)*
}
) => {
#[allow(non_camel_case_types)]
pub struct $export;
impl Command for $export {
2019-07-24 00:22:11 +02:00
fn run(&self, $args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream, ShellError> {
fn command($args: EvaluatedCommandArgs, ( $($param_name),*, ): ( $($param_type),*, )) -> Result<OutputStream, ShellError> {
let output = $body;
Ok(output.boxed().to_output_stream())
}
2019-07-24 00:22:11 +02:00
let $args = $args.evaluate_once(registry)?;
2019-07-15 23:16:27 +02:00
let tuple = ( $($extract ,)* );
command( $args, tuple )
}
fn name(&self) -> &str {
stringify!($config_name)
}
2019-08-02 21:15:07 +02:00
fn config(&self) -> $crate::parser::registry::Signature {
$crate::parser::registry::Signature {
name: self.name().to_string(),
positional: vec![$($mandatory_positional)*],
rest_positional: false,
2019-07-13 04:07:06 +02:00
is_filter: false,
is_sink: false,
named: {
2019-07-08 18:44:53 +02:00
use $crate::parser::registry::NamedType;
#[allow(unused_mut)]
let mut named: indexmap::IndexMap<String, NamedType> = indexmap::IndexMap::new();
$(
2019-07-15 23:16:27 +02:00
named.insert(stringify!($named_param).to_string(), $crate::parser::registry::NamedType::$named_kind);
)*
named
}
}
}
}
};
// switch
(
Named { $export:tt $args:ident $body:block }
Positional { $($positional_count:tt)* }
2019-07-15 23:16:27 +02:00
Rest { -- $param_name:ident : Switch , $($rest:tt)* }
2019-08-02 21:15:07 +02:00
Signature {
name: $config_name:tt,
mandatory_positional: vec![ $($mandatory_positional:tt)* ],
optional_positional: vec![ $($optional_positional:tt)* ],
rest_positional: $rest_positional:tt,
named: {
$($config_named:tt)*
}
}
Function {
$($function:tt)*
}
Extract {
$($extract:tt)*
}
) => {
command!(
Named { $export $args $body }
Positional { $($positional_count)* + 1 }
Rest { $($rest)* }
2019-08-02 21:15:07 +02:00
Signature {
name: $config_name,
mandatory_positional: vec![ $($mandatory_positional)* ],
optional_positional: vec![ $($optional_positional)* ],
rest_positional: $rest_positional,
named: {
$($config_named)*
2019-07-15 23:16:27 +02:00
($param_name : Switch : Switch)
}
}
Function {
$($function)* ($param_name : Switch)
}
Extract {
2019-07-15 23:16:27 +02:00
$($extract)* {
use std::convert::TryInto;
$args.get(stringify!($param_name)).clone().try_into()?
2019-07-15 23:16:27 +02:00
}
}
);
};
// mandatory named arguments
(
Named { $export:tt $args:ident $body:block }
Positional { $($positional_count:tt)* }
2019-07-15 23:16:27 +02:00
Rest { -- $param_name:ident : $param_kind:ty , $($rest:tt)* }
2019-08-02 21:15:07 +02:00
Signature {
name: $config_name:tt,
mandatory_positional: vec![ $($mandatory_positional:tt)* ],
optional_positional: vec![ $($optional_positional:tt)* ],
rest_positional: $rest_positional:tt,
named: {
$($config_named:tt)*
}
}
Function {
$($function:tt)*
}
Extract {
$($extract:tt)*
}
) => {
command!(
Named { $export $args $body }
Positional { $($positional_count)* + 1 }
Rest { $($rest)* }
2019-08-02 21:15:07 +02:00
Signature {
name: $config_name,
mandatory_positional: vec![ $($mandatory_positional)* ],
optional_positional: vec![ $($optional_positional)* ],
rest_positional: $rest_positional,
named: {
$($config_named)*
($param_name : Mandatory(NamedValue::Single))
}
}
Function {
$($function)* ($param_name : $param_kind)
}
Extract {
2019-07-15 23:16:27 +02:00
$($extract)* {
use std::convert::TryInto;
$args.get(stringify!($param_name)).clone().try_into()?
2019-07-15 23:16:27 +02:00
}
}
);
};
// optional named arguments
(
Named { $export:tt $args:ident $body:block }
Positional { $($positional_count:tt)* }
2019-07-15 23:16:27 +02:00
Rest { -- $param_name:ident ? : $param_kind:ty , $($rest:tt)* }
2019-08-02 21:15:07 +02:00
Signature {
name: $config_name:tt,
mandatory_positional: vec![ $($mandatory_positional:tt)* ],
optional_positional: vec![ $($optional_positional:tt)* ],
rest_positional: $rest_positional:tt,
named: {
$($config_named:tt)*
}
}
Function {
$($function:tt)*
}
Extract {
$($extract:tt)*
}
) => {
command!(
Named { $export $args $body }
Positional { $($positional_count)* + 1 }
Rest { $($rest)* }
2019-08-02 21:15:07 +02:00
Signature {
name: $config_name,
mandatory_positional: vec![ $($mandatory_positional)* ],
optional_positional: vec![ $($optional_positional)* ],
rest_positional: $rest_positional,
named: {
$($config_named)*
($param_name : Optional(NamedValue::Single))
}
}
Function {
$($function)* ($param_name : $param_kind)
}
Extract {
2019-07-15 23:16:27 +02:00
$($extract)* {
use std::convert::TryInto;
$args.get(stringify!($param_name)).clone().try_into()?
2019-07-15 23:16:27 +02:00
}
}
);
};
2019-07-12 21:22:08 +02:00
// mandatory positional block
(
Named { $export:ident $args:ident $body:block }
Positional { $($positional_count:tt)* }
2019-07-15 23:16:27 +02:00
Rest { $param_name:ident : Block , $($rest:tt)* }
2019-08-02 21:15:07 +02:00
Signature {
2019-07-12 21:22:08 +02:00
name: $config_name:tt,
mandatory_positional: vec![ $($mandatory_positional:tt)* ],
optional_positional: vec![ $($optional_positional:tt)* ],
rest_positional: $rest_positional:tt,
named: {
$($config_named:tt)*
}
}
Function {
$($function:tt)*
}
Extract {
$($extract:tt)*
}
) => {
command!(
Named { $export $args $body }
Positional { $($positional_count)* + 1 }
Rest { $($rest)* }
2019-08-02 21:15:07 +02:00
Signature {
2019-07-12 21:22:08 +02:00
name: $config_name,
mandatory_positional: vec![ $($mandatory_positional)* $crate::parser::registry::PositionalType::mandatory_block(
stringify!($param_name)
), ],
optional_positional: vec![ $($optional_positional)* ],
rest_positional: $rest_positional,
named: {
$($config_named)*
}
}
Function {
$($function)* ($param_name : Block)
}
Extract {
$($extract:tt)* {
use $crate::data::types::ExtractType;
2019-07-12 21:22:08 +02:00
let value = $args.expect_nth($($positional_count)*)?;
Block::extract(value)?
}
}
);
};
// mandatory positional argument
(
Named { $export:ident $args:ident $body:block }
Positional { $($positional_count:tt)* }
2019-07-15 23:16:27 +02:00
Rest { $param_name:ident : $param_kind:ty , $($rest:tt)* }
2019-08-02 21:15:07 +02:00
Signature {
name: $config_name:tt,
mandatory_positional: vec![ $($mandatory_positional:tt)* ],
optional_positional: vec![ $($optional_positional:tt)* ],
rest_positional: $rest_positional:tt,
named: {
$($config_named:tt)*
}
}
Function {
$($function:tt)*
}
Extract {
$($extract:tt)*
}
) => {
command!(
Named { $export $args $body }
Positional { $($positional_count)* + 1 }
Rest { $($rest)* }
2019-08-02 21:15:07 +02:00
Signature {
name: $config_name,
mandatory_positional: vec![ $($mandatory_positional)* $crate::parser::registry::PositionalType::mandatory(
2019-07-15 23:16:27 +02:00
stringify!($param_name), <$param_kind>::syntax_type()
), ],
optional_positional: vec![ $($optional_positional)* ],
rest_positional: $rest_positional,
named: {
$($config_named)*
}
}
Function {
$($function)* ($param_name : $param_kind)
}
Extract {
$($extract:tt)* {
use $crate::data::types::ExtractType;
2019-07-06 00:08:58 +02:00
let value = $args.expect_nth($($positional_count)*)?;
2019-07-15 23:16:27 +02:00
<$param_kind>::extract(&value)?
}
}
);
};
2019-07-15 23:16:27 +02:00
($export:ident as $config_name:tt ( $args:ident , $($command_rest:tt)* ) $body:block) => {
command!(
Named { $export $args $body }
Positional { 0 }
Rest { $($command_rest)* }
2019-08-02 21:15:07 +02:00
Signature {
name: $config_name,
mandatory_positional: vec![],
optional_positional: vec![],
rest_positional: false,
named: {}
}
Function {
}
Extract {
}
);
};
}