1 /* 2 * hunt-console eases the creation of beautiful and testable command line interfaces. 3 * 4 * Copyright (C) 2018-2019, HuntLabs 5 * 6 * Website: https://www.huntlabs.net 7 * 8 * Licensed under the Apache-2.0 License. 9 * 10 */ 11 12 module hunt.console.input.InputOption; 13 14 import hunt.console.error.InvalidArgumentException; 15 import hunt.console.error.LogicException; 16 import hunt.console.util.StringUtils; 17 import hunt.text.Common; 18 import std.string; 19 import hunt.Exceptions; 20 import std.conv; 21 22 class InputOption 23 { 24 enum int VALUE_NONE = 1; 25 enum int VALUE_REQUIRED = 2; 26 enum int VALUE_OPTIONAL = 4; 27 enum int VALUE_IS_ARRAY = 8; 28 29 private string name; 30 private string shortcut; 31 private int mode; 32 private string description; 33 private string defaultValue; 34 35 this(string name) 36 { 37 this(name, null, VALUE_NONE, null, null); 38 } 39 40 this(string name, string shortcut) 41 { 42 this(name, shortcut, VALUE_NONE, null, null); 43 } 44 45 this(string name, string shortcut, int mode) 46 { 47 this(name, shortcut, mode, null, null); 48 } 49 50 this(string name, string shortcut, int mode, string description) 51 { 52 this(name, shortcut, mode, description, null); 53 } 54 55 this(string name, string shortcut, int mode, string description, string defaultValue) 56 { 57 if (name.startsWith("--")) { 58 name = name.substring(2); 59 } 60 61 if (name.isEmpty()) { 62 throw new InvalidArgumentException("An option name cannot be empty."); 63 } 64 65 if (shortcut !is null && shortcut.isEmpty()) { 66 shortcut = null; 67 } 68 69 if (shortcut !is null) { 70 shortcut = StringUtils.ltrim(shortcut, '-'); 71 if (shortcut.isEmpty()) { 72 throw new IllegalArgumentException("An option shortcut cannot be empty."); 73 } 74 } 75 76 if (mode > 15 || mode < 1) { 77 throw new InvalidArgumentException("Option mode " ~ mode.to!string ~ " is not valid"); 78 } 79 80 this.name = name; 81 this.shortcut = shortcut; 82 this.mode = mode; 83 this.description = description; 84 85 setDefaultValue(defaultValue); 86 } 87 88 string getShortcut() 89 { 90 return shortcut; 91 } 92 93 string getName() 94 { 95 return name; 96 } 97 98 bool acceptValue() 99 { 100 return isValueRequired() || isValueOptional(); 101 } 102 103 bool isValueRequired() 104 { 105 return (mode & VALUE_REQUIRED) == VALUE_REQUIRED; 106 } 107 108 bool isValueOptional() 109 { 110 return (mode & VALUE_OPTIONAL) == VALUE_OPTIONAL; 111 } 112 113 bool isArray() 114 { 115 return (mode & VALUE_IS_ARRAY) == VALUE_IS_ARRAY; 116 } 117 118 void setDefaultValue(string defaultValue) 119 { 120 if ((mode & VALUE_NONE) == VALUE_NONE && defaultValue !is null) { 121 throw new LogicException("Cannot set a default value when using InputOption.VALUE_NONE mode."); 122 } 123 124 if (isArray()) { 125 // todo implement 126 } 127 128 this.defaultValue = acceptValue() ? defaultValue : null; 129 } 130 131 string getDefaultValue() 132 { 133 return defaultValue; 134 } 135 136 string getDescription() 137 { 138 return description; 139 } 140 141 override bool opEquals(Object o) 142 { 143 if (this is o) return true; 144 if (!(cast(InputOption)o !is null)) return false; 145 146 InputOption that =cast(InputOption) o; 147 148 if (isArray() != that.isArray()) return false; 149 if (isValueRequired() != that.isValueRequired()) return false; 150 if (isValueOptional() != that.isValueOptional()) return false; 151 if (defaultValue !is null ? !(defaultValue == that.defaultValue) : that.defaultValue !is null) return false; 152 if (name !is null ? !(name == that.name) : that.name !is null) return false; 153 if (shortcut !is null ? !(shortcut == that.shortcut) : that.shortcut !is null) return false; 154 155 return true; 156 } 157 158 override size_t toHash() @trusted nothrow 159 { 160 int result = name !is null ? cast(int)(name.hashOf()) : 0; 161 result = 31 * result + (shortcut !is null ? cast(int)(shortcut.hashOf()) : 0); 162 result = 31 * result + mode; 163 result = 31 * result + (description !is null ? cast(int)(description.hashOf()) : 0); 164 result = 31 * result + (defaultValue !is null ? cast(int)(defaultValue.hashOf()) : 0); 165 return result; 166 } 167 }