Open matanlurey opened 6 years ago
I think there's a general need for a good API to access heterogeneous untyped information. We have something like this for JSON-RPC 2 parameters, but it would be nice to generalize it enough that it could be used for parsed arguments, JSON/YAML objects, and so on. As the pressures to avoid dynamic values get stronger, this will be more and more relevant.
The args package already has a delineation between bool "flags" and other-type "options." What about even just an is
or has
method for accessing bools?
var argParser = new ArgParser()
..addFlag('help');
var argResults = argParser.parse(args);
if (argResults['help']) { ... } // Error: Conditions must have a static type of 'bool'.
if (argResults['help'] == true) { ... } // What I have to do today. :(
if (argResults.has('help')) { ... } // Would be nice.
if (argResults.isNot('help')) { ... } // Lends itself nicely to negatable.
I'm looking at disabling implicit downcasts in the flutter tool, and a large portion come from ArgResults.[]
returning dynamic. I'm working around this with a typed wrapper which exposes getOption
, getFlag
and getMultiOption
in https://github.com/flutter/flutter/pull/31679.
It would be great to have something similar in the args package.
You can do a lot with extensions these days.
extension ArgResultGetters on ArgResults {
bool? optionalFlag(String name) => this[name] as bool?;
bool flag(String name, {bool defaultValue: false}) => (this[name] as bool?) ?? defaultValue;
bool has(String name) => this[name] != null;
String stringOption(String name, {String defaultValue = ""}) => (this[name] as String?) ?? defaultValue;
int intOption(String name, {int defaultValue = -1}) {
var value = this[name];
if (value is! String) return defaultValue;
return int.tryParse(value) ?? defaultValue;
}
T option<T>(String name) => this[name] as T;
List<String> multiOption(String name) => this[name] as List<String>;
}
This is a runtime failure in Dart2:
... but patterns like this are really common.
I'd like to see a series of helper methods to make it easier to get common types and collections out of ArgResults, even if all they do behind the scenes is a combination of
as
and collection casts. Ideas:Primitives
bool readBool(String name)
double readDouble(String name)
int readInt(String name)
String readString(String name)
Collections
List<String> readStringList(String name)
Thoughts?
/cc @nex3 @natebosch