Skip to content

Commit

Permalink
Remove @TrailingArguments (#159)
Browse files Browse the repository at this point in the history
* Rename Config.endOfArgs -> endOfNamedArgs

* Refactor consumeValuesFromCLI

* Refactor parseAll

* Remove @TrailingArguments

* Add unit tests
  • Loading branch information
andrey-zherikov authored Feb 1, 2024
1 parent 6a13cd0 commit e206434
Show file tree
Hide file tree
Showing 7 changed files with 160 additions and 119 deletions.
28 changes: 3 additions & 25 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -541,27 +541,6 @@ The following usages of the argument in the command line are equivalent:
`--name John`, `--name=John`, `--n John`, `--n=John`, `-nJohn`, `-n John`, `-n=John`. Note that any other character can
be used instead of `=` – see [Parser customization](#parser-customization) for details.

### Trailing arguments

A lone double dash terminates argument parsing by default. It is used to separate program arguments from other
parameters (e.g., arguments to be passed to another program). To store trailing arguments, simply add a data member of
type `string[]` with `TrailingArguments` UDA:

```d
struct T
{
string a;
string b;
@TrailingArguments string[] args;
}
assert(CLI!T.parseArgs!((T t) { assert(t == T("A","",["-b","B"])); })(["-a","A","--","-b","B"]) == 0);
```

Note that any other character sequence can be used instead of `--` – see [Parser customization](#parser-customization)
for details.

### Optional and required arguments

Arguments can be marked as required or optional by adding `.Required()` or `.Optional()` to UDA. If required argument is
Expand Down Expand Up @@ -901,8 +880,6 @@ struct T
@(PositionalArgument(0).Description(() => "This is a help text for param0. Very very very very very very very very very very very very very very very very very very very long text")) string param0;
@(PositionalArgument(1).AllowedValues!(["q","a"])) string param1;
@TrailingArguments string[] args;
}
CLI!T.parseArgs!((T t) {})(["-h"]);
Expand Down Expand Up @@ -1600,9 +1577,10 @@ assert(CLI!(cfg, T).parseArgs!((T t) { assert(t == T(["1","2","3","4","5"])); })

Default is dash (`-`).

### End of arguments
### End of named arguments

`Config.endOfArgs` – the string that conventionally marks the end of all arguments.
`Config.endOfNamedArgs` – the string that conventionally marks the end of all named arguments. All arguments that are specified
after this one are treated as positional regardless to the value which can start with `namedArgPrefix` (dash `-` by default).

Default is double dash (`--`).

Expand Down
4 changes: 0 additions & 4 deletions source/argparse/api/argument.d
Original file line number Diff line number Diff line change
Expand Up @@ -346,7 +346,3 @@ unittest
assert(uda.info.minValuesCount == 0);
assert(uda.info.maxValuesCount == 0);
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

struct TrailingArguments {}
6 changes: 3 additions & 3 deletions source/argparse/config.d
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,11 @@ struct Config
char namedArgPrefix = '-';

/**
The string that conventionally marks the end of all options.
Assigning an empty string to `endOfArgs` effectively disables it.
The string that conventionally marks the end of all named arguments.
Assigning an empty string effectively disables it.
Defaults to "--".
*/
string endOfArgs = "--";
string endOfNamedArgs = "--";

/**
If set then argument names are case-sensitive.
Expand Down
33 changes: 1 addition & 32 deletions source/argparse/internal/command.d
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module argparse.internal.command;
import argparse.config;
import argparse.param;
import argparse.result;
import argparse.api.argument: TrailingArguments, NamedArgument, NumberOfValues;
import argparse.api.argument: NamedArgument, NumberOfValues;
import argparse.api.subcommand: match, isSubCommand;
import argparse.internal.arguments: Arguments, ArgumentInfo, finalize;
import argparse.internal.argumentuda: ArgumentUDA;
Expand Down Expand Up @@ -157,9 +157,6 @@ package struct Command
}


void delegate(ref string[] args) setTrailingArgs;



const(string)[] suggestions(string prefix) const
{
Expand Down Expand Up @@ -373,11 +370,6 @@ package(argparse) Command createCommand(Config config, COMMAND_TYPE)(ref COMMAND

res.completeFuncs = [staticMap!(getArgumentCompleteFunction, typeTraits.argumentUDAs)];

res.setTrailingArgs = (ref string[] args)
{
.setTrailingArgs(receiver, args);
};

res.subCommands.add([typeTraits.subCommandInfos]);

static foreach(subcmd; typeTraits.subCommands)
Expand Down Expand Up @@ -421,26 +413,3 @@ private auto ParsingSubCommandCreate(Config config, COMMAND_TYPE, TARGET)(ref TA
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

private void setTrailingArgs(RECEIVER)(ref RECEIVER receiver, ref string[] rawArgs)
{
alias ORIG_TYPE = RECEIVER;

alias symbols = getSymbolsByUDA!(ORIG_TYPE, TrailingArguments);

static assert(symbols.length <= 1, "Type "~ORIG_TYPE.stringof~" must have at most one 'TrailingArguments' UDA");
static if(symbols.length == 1)
{
enum symbol = __traits(identifier, symbols[0]);
auto target = &__traits(getMember, receiver, symbol);

static if(__traits(compiles, { *target = rawArgs; }))
*target = rawArgs;
else
static assert(false, "Type '"~typeof(*target).stringof~"' of `"~ORIG_TYPE.stringof~"."~symbol~"` is not supported for 'TrailingArguments' UDA");

rawArgs = [];
}
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4 changes: 2 additions & 2 deletions source/argparse/internal/completer.d
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
module argparse.internal.completer;

import argparse.config;
import argparse.api.argument: NamedArgument, Description, TrailingArguments;
import argparse.api.argument: NamedArgument, PositionalArgument, Description;
import argparse.api.command: Command, Description, ShortDescription;
import argparse.api.restriction: MutuallyExclusive;
import argparse.api.subcommand: SubCommand, Default;
Expand Down Expand Up @@ -77,7 +77,7 @@ private struct CompleteCmd
bool fish;
}

@TrailingArguments
@PositionalArgument(0)
string[] args;

void execute(Config config, COMMAND)()
Expand Down
Loading

0 comments on commit e206434

Please sign in to comment.