framework icon indicating copy to clipboard operation
framework copied to clipboard

Argument parsing for required and optional arguments should have a flexible order

Open arqunis opened this issue 4 years ago • 1 comments
trafficstars

The current argument parsing system for commands enforces a strict order of the types of arguments, which proceeds as:

  1. Required arguments
  2. Optional arguments
  3. Variadic argument or #[rest] argument

Each type of argument may be absent, but violating this order will result in a macro error. What this issue proposes, however, is to break the strict order for required and optional arguments. This would allow for backtracking when parsing arguments for a command.

For example, for the following command:

#[command]
async fn boogie(ctx: FrameworkContext, msg: &Message, user2: Option<UserId>, user: UserId) -> CommandResult {
    // ....
}

no error would originate from the macro. Instead, if just one argument is given, user2 will be None, while user will be populated with the argument. And in the case of two arguments, user2 will be the first argument, and user the second argument.

Order between required/optional arguments and a variadic/#[rest] argument will stay the same and will have to be uphold.

arqunis avatar Mar 21 '21 13:03 arqunis

Most of the finicky backtracking business can be implemented in declarative macros, which is very nice for code conciseness. In an experimental alternative framework I made such a macro that can so-far parse:

  • T
  • #[rest] T
  • #[rest] &str
  • Option<T> (greedy)
  • #[lazy] Option<T> (lazy)
  • Vec<T> (greedy)

Where T: serenity::utils::Parse. All of these can be arranged arbitrarily.

It's used like this, which can relatively painlessly be generated by a procedural macro I think

let arg_string = "hello 1 2 3 foo bar";
let (hello, empty, numbers, foo_bar_member) = parse_args!(ctx, msg, arg_string =>
    (&str),
    #[lazy] (Option<&str>),
    (Vec<u32>),
    #[rest] (serenity::model::prelude::Member),
).await?

kangalio avatar Mar 28 '21 15:03 kangalio