OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. |
| 4 |
| 5 library args.src.option; |
| 6 |
| 7 import 'package:collection/wrappers.dart'; |
| 8 |
| 9 /// Creates a new [Option]. |
| 10 /// |
| 11 /// Since [Option] doesn't have a public constructor, this lets [ArgParser] |
| 12 /// get to it. This function isn't exported to the public API of the package. |
| 13 Option newOption(String name, String abbreviation, String help, |
| 14 String valueHelp, List<String> allowed, Map<String, String> allowedHelp, |
| 15 defaultValue, Function callback, OptionType type, |
| 16 {bool negatable, bool hide: false}) { |
| 17 return new Option._(name, abbreviation, help, valueHelp, allowed, allowedHelp, |
| 18 defaultValue, callback, type, negatable: negatable, hide: hide); |
| 19 } |
| 20 |
| 21 /// A command-line option. Includes both flags and options which take a value. |
| 22 class Option { |
| 23 final String name; |
| 24 final String abbreviation; |
| 25 final List<String> allowed; |
| 26 final defaultValue; |
| 27 final Function callback; |
| 28 final String help; |
| 29 final String valueHelp; |
| 30 final Map<String, String> allowedHelp; |
| 31 final OptionType type; |
| 32 final bool negatable; |
| 33 final bool hide; |
| 34 |
| 35 /// Whether the option is boolean-valued flag. |
| 36 bool get isFlag => type == OptionType.FLAG; |
| 37 |
| 38 /// Whether the option takes a single value. |
| 39 bool get isSingle => type == OptionType.SINGLE; |
| 40 |
| 41 /// Whether the option allows multiple values. |
| 42 bool get isMultiple => type == OptionType.MULTIPLE; |
| 43 |
| 44 Option._(this.name, this.abbreviation, this.help, this.valueHelp, |
| 45 List<String> allowed, Map<String, String> allowedHelp, this.defaultValue, |
| 46 this.callback, this.type, {this.negatable, this.hide: false}) : |
| 47 this.allowed = allowed == null ? |
| 48 null : new UnmodifiableListView(allowed), |
| 49 this.allowedHelp = allowedHelp == null ? |
| 50 null : new UnmodifiableMapView(allowedHelp) { |
| 51 |
| 52 if (name.isEmpty) { |
| 53 throw new ArgumentError('Name cannot be empty.'); |
| 54 } else if (name.startsWith('-')) { |
| 55 throw new ArgumentError('Name $name cannot start with "-".'); |
| 56 } |
| 57 |
| 58 // Ensure name does not contain any invalid characters. |
| 59 if (_invalidChars.hasMatch(name)) { |
| 60 throw new ArgumentError('Name "$name" contains invalid characters.'); |
| 61 } |
| 62 |
| 63 if (abbreviation != null) { |
| 64 if (abbreviation.length != 1) { |
| 65 throw new ArgumentError('Abbreviation must be null or have length 1.'); |
| 66 } else if(abbreviation == '-') { |
| 67 throw new ArgumentError('Abbreviation cannot be "-".'); |
| 68 } |
| 69 |
| 70 if (_invalidChars.hasMatch(abbreviation)) { |
| 71 throw new ArgumentError('Abbreviation is an invalid character.'); |
| 72 } |
| 73 } |
| 74 } |
| 75 |
| 76 /// Returns [value] if non-`null`, otherwise returns the default value for |
| 77 /// this option. |
| 78 /// |
| 79 /// For single-valued options, it will be [defaultValue] if set or `null` |
| 80 /// otherwise. For multiple-valued options, it will be an empty list or a |
| 81 /// list containing [defaultValue] if set. |
| 82 dynamic getOrDefault(value) { |
| 83 if (value != null) return value; |
| 84 |
| 85 if (!isMultiple) return defaultValue; |
| 86 if (defaultValue != null) return [defaultValue]; |
| 87 return []; |
| 88 } |
| 89 |
| 90 static final _invalidChars = new RegExp(r'''[ \t\r\n"'\\/]'''); |
| 91 } |
| 92 |
| 93 /// What kinds of values an option accepts. |
| 94 class OptionType { |
| 95 /// An option that can only be `true` or `false`. |
| 96 /// |
| 97 /// The presence of the option name itself in the argument list means `true`. |
| 98 static const FLAG = const OptionType._("OptionType.FLAG"); |
| 99 |
| 100 /// An option that takes a single value. |
| 101 /// |
| 102 /// Examples: |
| 103 /// |
| 104 /// --mode debug |
| 105 /// -mdebug |
| 106 /// --mode=debug |
| 107 /// |
| 108 /// If the option is passed more than once, the last one wins. |
| 109 static const SINGLE = const OptionType._("OptionType.SINGLE"); |
| 110 |
| 111 /// An option that allows multiple values. |
| 112 /// |
| 113 /// Example: |
| 114 /// |
| 115 /// --output text --output xml |
| 116 /// |
| 117 /// In the parsed [ArgResults], a multiple-valued option will always return |
| 118 /// a list, even if one or no values were passed. |
| 119 static const MULTIPLE = const OptionType._("OptionType.MULTIPLE"); |
| 120 |
| 121 final String name; |
| 122 |
| 123 const OptionType._(this.name); |
| 124 } |
OLD | NEW |