Clap, enum and HashSet

I have a struct that looks something like this (and is part of a clap subcommand):

#[derive(Debug, Args)]
pub struct MkUserCmd {
  /// Grant account permission PERM.
  #[arg(short, long,
    value_name = "PERM",
    value_parser = clap::value_parser!(Perm),
    action = ArgAction::Append,
  )]
  pub permission: HashSet<Perm>,

  /// User's name.
  pub name: String
}

Perm is a ValueEnum enum that's just a bunch of permissions.

The idea is to allow the user to pass permissions that will be granted to the new user, but I want to put them in a HashSet.

Everything builds successfully, but when I run the parser it says it is missing arguments to the --permission flag (even if it isn't passed at all). If I pass --permission with a valid permission I get a downcast panic.

I have used Vec for these kind of things previously, and that has worked fine, and I will fall back to that -- but I'm curious if this can be made to work. I get the feeling that this should be possible.

Sets and Maps have not been added as recognized containers for multiple occurrences. One reason is we don't know whether the user intends repeats to be conflicts or overwrites.

So clap is seeing the field's type as HashSet<Perm> but you gave it a parser for Perm, so there is a type conflict. I'd like that to be reported at compile time but haven't worked through how to do that yet.

The only option at this time is to do Vec<Perm>.

4 Likes