Created
May 20, 2022 02:30
-
-
Save lukaskj/7eb28068a04d589b31c941c48e1a7fb7 to your computer and use it in GitHub Desktop.
Haxe argument flags helper
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package util; | |
import haxe.io.Path; | |
enum OptionType { | |
String; | |
Bool; | |
Int; | |
} | |
class Option { | |
public var name:String; | |
public var value:Dynamic; | |
public var type:OptionType; | |
public var description:String; | |
public var required:Bool; | |
public function new(name:String, description:String, ?required:Bool = false, ?type:OptionType = OptionType.String) { | |
this.name = name; | |
// this.value = value; | |
this.type = type; | |
this.description = description; | |
this.required = required; | |
} | |
} | |
class Getopt { | |
private static var instance:Getopt = null; | |
private static var valid:Bool = true; | |
private var options:Array<Option>; | |
private var mappedOptions:Map<String, Option> = []; | |
private var mappedArguments:Map<String, Dynamic> = []; | |
private function new() {} | |
public static function build(options:Array<Option>, ?strict:Bool = false):Getopt { | |
var instance = getInstance(); | |
instance.options = options; | |
instance.mapOptions(); | |
valid = instance.mapArgumentsAndValidate(); | |
return instance; | |
} | |
public static function getInstance():Getopt { | |
if (instance == null) { | |
instance = new Getopt(); | |
} | |
return instance; | |
} | |
private function mapOptions():Void { | |
this.options.sort((opt1, opt2) -> opt2.required ? 1 : -1); | |
for (opt in this.options) { | |
this.mappedOptions.set(opt.name, opt); | |
} | |
} | |
private function mapArgumentsAndValidate():Bool { | |
var args:Array<String> = Sys.args(); | |
var i:Int = 0; | |
var regDashes = ~/^\-?\-/; | |
var regEquals = ~/=?/; | |
while (i < args.length) { | |
var arg:String = args[i]; | |
var name:String; | |
var value:Dynamic = null; | |
// if (StringTools.startsWith(arg, '--')) { | |
// arg = regDashes.replace(arg, ''); | |
if (StringTools.contains(arg, '=')) { | |
var splitArgs = arg.split('='); | |
name = splitArgs[0]; | |
value = splitArgs[1]; | |
} else { | |
name = arg; | |
if (args[i + 1] != null && this.mappedOptions.exists(name)) { | |
value = args[i + 1]; | |
i++; | |
} | |
} | |
this.mappedArguments.set(name, value); | |
i++; | |
} | |
for (optName => option in this.mappedOptions) { | |
var value = this.mappedArguments.get(optName); | |
var existsValue:Bool = this.mappedArguments.exists(optName) && value != null; | |
switch (option.type) { | |
// case OptionType.Int: | |
// option.value = cast(value, Int); // All will be strings | |
case OptionType.Bool: | |
option.value = value != null; | |
default: | |
option.value = value; | |
} | |
if (option.required && !existsValue) { | |
this.line(''); | |
this.line('Option "${option.description}" (${option.name}) is required.'); | |
return false; | |
} | |
} | |
return true; | |
} | |
public function isValid():Bool { | |
return valid; | |
} | |
private function line(str:Dynamic):Void { | |
return Sys.println(str); | |
} | |
public function usage():Void { | |
var program:String = Path.withoutDirectory(Sys.programPath()); | |
var arguments:Array<String> = []; | |
var mandatoryArguments:Array<String> = []; | |
var nonMandatoryArguments:Array<String> = []; | |
arguments = this.options.map(opt -> '-${opt.name}'); | |
mandatoryArguments = this.options.filter(opt -> opt.required).map(opt -> '${opt.name} ${this.cleanStr(opt.name.toUpperCase())}'); | |
nonMandatoryArguments = this.options.filter(opt -> !opt.required).map(opt -> '[${opt.name} ${this.cleanStr(opt.name.toUpperCase())}]'); | |
this.line(''); | |
this.line('Usage:'); | |
this.line('$program ' + mandatoryArguments.join(' ') + ' ' + nonMandatoryArguments.join(' ')); | |
this.line(''); | |
this.line('Arguments:'); | |
for (opt in this.options) { | |
this.line('${opt.name}\t\t${opt.description}'); | |
} | |
} | |
private function cleanStr(str:String):String { | |
return ~/[^0-9a-zA-Z]/.replace(str, ''); | |
} | |
public function get(key:String):Dynamic { | |
if (!this.mappedOptions.exists(key)) { | |
return null; | |
} | |
return this.mappedOptions.get(key).value; | |
} | |
public function exists(key:String):Bool { | |
return this.mappedOptions.exists(key); | |
} | |
public function all():Map<String, Option> { | |
return this.mappedOptions; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment