args icon indicating copy to clipboard operation
args copied to clipboard

Add a way to create options that get parsed into another type

Open natebosch opened this issue 5 years ago • 2 comments

See discussion in https://github.com/dart-lang/args/pull/145

I think it should be feasible to have something like:

  void addConvertedOption<T>(String name,
      T Function(String) convert,
      {String? abbr,
      String? help,
      String? valueHelp,
      Iterable<String>? allowed,
      Map<String, String>? allowedHelp,
      T? defaultsTo,
      void Function(T?)? callback,
      bool hide = false});

This could make it a bit more ergonomic for some things like needing to int.parse an option.

The priority isn't high anymore because the main pain point that we had previously was that defaultsTo was statically dynamic to allow either String or List<String> before we pulled the multi option concept out from addOption.

Some complications:

  • Does it make sense to include allowed as Iterable<String> or should we make that Iterable<T>?
  • How will we print the value in the usage text? Will it use defaultsTo.toString() always, or would we need an optional String Function(T) usageText callback as well?

natebosch avatar Dec 11 '20 03:12 natebosch

  • Does it make sense to include allowed as Iterable<String> or should we make that Iterable<T>

I think Iterable<T> does sound more appropriate?

  • How will we print the value in the usage text? Will it use defaultsTo.toString() always, or would we need an optional String Function(T) usageText callback as well?

Hmm, I think what you want to show here is what the default command line option would look like. That almost makes me thing that defaultsTo should actually be typed String, and be converted, which seems weird but might give the best results? Not convinced though.

jakemac53 avatar Dec 11 '20 16:12 jakemac53

I've thought about this before, but my impression is that it doesn't add enough value to carry its weight. Fundamentally, argument parsing is about taking in strings and doing something useful with them. They always come in as strings and the arg parser itself doesn't have enough domain knowledge to know what type to convert them to. If we let users pass in the conversion, then the arg parser isn't really adding any value. It's just, like, calling the callback you gave it. You may as well just call that yourself.

I could maybe see it worthwhile to support a couple of hard-coded common types. Maybe even just ints:

  void addIntOption(String name,
      {String? abbr,
      String? help,
      String? valueHelp,
      Iterable<int>? allowed,
      Map<int, String>? allowedHelp,
      int? defaultsTo,
      void Function(int)? callback,
      bool hide = false});

But a generic user-provided conversion doesn't seem to add much value to me.

munificent avatar Dec 16 '20 01:12 munificent