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.descriptor.ConsoleDescription; 13 14 import std.string; 15 16 import hunt.console.Console; 17 import hunt.console.error.InvalidArgumentException; 18 import hunt.console.command.Command; 19 import hunt.console.descriptor.ConsoleDescription; 20 21 import hunt.collection.ArrayList; 22 import hunt.collection.HashMap; 23 import hunt.collection.List; 24 import hunt.collection.Map; 25 import hunt.Integer; 26 27 class ConsoleDescription 28 { 29 public static string GLOBAL_NAMESPACE = "_global"; 30 31 private Console application; 32 33 private string namespace; 34 35 private Map!(string, List!(string)) namespaces; 36 37 private Map!(string, Command) commands; 38 39 private Map!(string, Command) aliases; 40 41 public this(Console application) 42 { 43 this(application, null); 44 } 45 46 public this(Console application, string namespace) 47 { 48 this.application = application; 49 this.namespace = namespace; 50 } 51 52 public Map!(string, List!(string)) getNamespaces() 53 { 54 if (namespaces is null) { 55 inspectConsole(); 56 } 57 58 return namespaces; 59 } 60 61 public Map!(string, Command) getCommands() 62 { 63 if (commands is null) { 64 inspectConsole(); 65 } 66 67 return commands; 68 } 69 70 public Command getCommand(string name) 71 { 72 if (!commands.containsKey(name) && !aliases.containsKey(name)) { 73 throw new InvalidArgumentException(format("Command %s does not exist.", name)); 74 } 75 76 if (commands.containsKey(name)) { 77 return commands.get(name); 78 } 79 80 return aliases.get(name); 81 } 82 83 private void inspectConsole() 84 { 85 commands = new HashMap!(string, Command)(); 86 aliases = new HashMap!(string, Command)(); 87 namespaces = new HashMap!(string, List!(string))(); 88 89 Map!(string, Command) all; 90 if (namespace is null) { 91 all = application.all(); 92 } else { 93 all = application.all(namespace); 94 } 95 96 foreach (string k ,Map!(string, Command) v ; sortCommands(all)) { 97 98 string namespace = k; 99 List!(string) names = new ArrayList!(string)(); 100 101 foreach (string subK , Command subV ; v) { 102 string name = subK; 103 Command command = subV; 104 if (command.getName() is null || command.getName().length == 0) { 105 continue; 106 } 107 108 if (command.getName() == name) { 109 commands.put(name, command); 110 } else { 111 aliases.put(name, command); 112 } 113 114 names.add(name); 115 } 116 117 namespaces.put(namespace, names); 118 } 119 } 120 121 private Map!(string, Map!(string, Command)) sortCommands(Map!(string, Command) commands) 122 { 123 Map!(string, Map!(string, Command)) namespacedCommands = new HashMap!(string, Map!(string, Command))(); 124 125 string key; 126 foreach (string k ,Command v ; commands) { 127 key = application.extractNamespace(k, new Integer(1)); 128 if (key is null || key.length == 0) { 129 key = GLOBAL_NAMESPACE; 130 } 131 132 if (!namespacedCommands.containsKey(key)) { 133 namespacedCommands.put(key, new HashMap!(string, Command)()); 134 } 135 namespacedCommands.get(key).put(k, v); 136 } 137 138 // todo sort 139 140 return namespacedCommands; 141 } 142 }