import 'package:libac_dart/argparse/types/Bool.dart'; import 'package:libac_dart/argparse/types/Integers.dart'; import 'package:libac_dart/argparse/types/String.dart'; import 'package:libac_dart/nbt/Stream.dart'; import 'Args.dart'; class CLIHelper { /// Generates usage info /// /// This will create a standard CLI Usage info string that can be directly printed to the console after the program header static String makeArgCLIHelp(Arguments defaults) { StringBuilder builder = StringBuilder(); List argNames = defaults.getArgNames(); for (String name in argNames) { builder.append("--${name}"); Argument arg = defaults.getArg(name)!; if (arg.hasValue) { builder.append("=<...>"); } builder.append( "\t\t\t${arg.description} ${(arg.getValue().toString() == "%" || arg.getType() == ArgumentType.BOOL) ? "" : "[Default: ${arg.getValue()}]"}\n"); } return builder.toString(); } /// Parses and returns the arguments list with keeping defaults in mind static Future parseArgs( List args, Arguments defaults) async { Arguments arguments = defaults.clone(); for (int i = 0; i < args.length; i++) { Argument arg = await _parseArgument(args[i]); Argument? defArg; if (defaults.hasArg(arg.name)) defArg = defaults.getArg(arg.name)!; if (!arg.hasValue) { if (defArg != null) { arg = defArg; } } arguments.setArg(arg); } return arguments; } static Future _parseArgument(String arg) async { if (arg.startsWith("--")) { var parts = arg.split("="); String name = await _getNamePart(parts[0]); if (parts.length == 1) return BoolArgument(name: name); else if (parts.length == 2) { String value = await _getValuePart(parts[1]); ArgumentType typeOfArg = await _getArgumentType(value); switch (typeOfArg) { case ArgumentType.INTEGER: { return IntegerArgument(name: name, value: int.parse(value)); } case ArgumentType.BOOL: { return BoolArgument(name: name); } case ArgumentType.DOUBLE: { return DoubleArgument(name: name, value: double.parse(value)); } case ArgumentType.STRING: { return StringArgument(name: name, value: value); } } } else throw new Exception("Argument is malformed"); } else throw new Exception("Not in a valid format"); } static Future _getNamePart(String value) async { return value.substring(2); } static Future _getValuePart(String entry) async { return entry; } static Future _getArgumentType(String input) async { try { int.parse(input); return ArgumentType.INTEGER; } catch (E) {} try { double.parse(input); return ArgumentType.DOUBLE; } catch (E) {} if (input.isEmpty) return ArgumentType.BOOL; else return ArgumentType.STRING; } }