public CommandArguments(IEnumerable <string> args, CommandArgumentParameters parameters) { m_args = new Dictionary <string, string>(); foreach (var arg in args) { if (!arg.StartsWith(parameters.CommandPrefix.ToString())) { continue; } var index = arg.IndexOf(parameters.CommandParamSeperator); if (index < 0) { // This is a flag m_args[arg.Substring(1)] = ""; continue; } var key = arg.Substring(1, index - 1); var value = arg.Substring(index + 1); m_args[key] = value; } if (parameters.OnValidate != null) { foreach (var parsedArg in m_args) { if (!parameters.OnValidate(parameters, parsedArg.Key, parsedArg.Value, out var error)) { throw new Exception(error); } } } }
/// <summary> /// Utility function to split up raw strings in string arrays, like Main(string[] args) /// </summary> /// <param name="raw">The raw commandline string</param> /// <param name="parameters">The parameters of how to parse the commandline</param> /// <returns>An enumerable of parsed commands</returns> public static IEnumerable <string> Split(string raw, CommandArgumentParameters parameters) { StringBuilder sb = new StringBuilder(); var result = new List <string>(); bool withinQuotes = false; foreach (var c in raw) { if (c == parameters.QuotationChar) { withinQuotes = !withinQuotes; continue; } if (c == parameters.CommandSeperator && !withinQuotes) { result.Add(sb.ToString()); sb.Clear(); continue; } sb.Append(c); } result.Add(sb.ToString()); return(result); }
/// <summary> /// Route the given arguments to a Command /// </summary> /// <param name="args">The arguments to be executed</param> /// <param name="parameters">The parameters to parse the arguments</param> public static void Execute(IEnumerable <string> args, CommandArgumentParameters parameters) { try { // TODO: rejoining strings like this will sometimes result in incorrect result. // Edge case, but possible. var reconstructedCmdLine = string.Join(new string(parameters.CommandSeperator, 1), args); var cmds = m_commands.Where(x => x.Key.IsMatch(reconstructedCmdLine)); var cmdCount = cmds.Count(); CommandData cmd; if (cmdCount == 1) { cmd = cmds.Single().Value; } else { Logger.Error($"No matching command found"); var bestMatches = m_commands.ToDictionary(x => x.Value.Attribute, x => LevenshteinDistance.Compute(x.Value.Attribute.CommandRegex, reconstructedCmdLine.Substring(0, Math.Min(reconstructedCmdLine.Length, x.Value.Attribute.CommandRegex.Length)))); var bestMatch = bestMatches.Where(x => x.Value <= 5).OrderBy(x => x.Value).FirstOrDefault(); if (bestMatch.Key != null) { Logger.Warning($"Did you mean \"{bestMatch.Key.FriendlyName}\"?"); } cmd = m_fallbackCommand; } var cmdArgs = new CommandArguments(args, parameters); OnPreExecute?.Invoke(cmdArgs); cmd.Method.Invoke(cmdArgs); } catch (Exception e) { if (e is AggregateException agg) { e = agg.InnerException; } Logger.Exception(e); } }
public CommandArguments(string args, CommandArgumentParameters parameters) : this(Split(args, parameters), parameters) { }
public static void Execute(string line, CommandArgumentParameters parameters) { Execute(CommandArguments.Split(line, parameters), parameters); }