namespace RTCSync.Options; public class OptionDispatcher { private readonly Dictionary _registredOptions = new(); public void Register(IOption option) { foreach (var optionName in option.OptionNames) { _registredOptions[optionName] = option; } } public void Execute(string[] args) { if (args.Length == 0) { PrintHelp(); return; } var flag = args[0]; if (!_registredOptions.TryGetValue(flag, out var command)) { Console.WriteLine($"Неизвестный параметр: {flag}"); PrintHelp(); return; } // Парсим все остальные аргументы как опции var commandArgs = ParseArguments(args.Skip(1).ToArray()); command.Execute(commandArgs); } private static OptionArgs ParseArguments(string[] args) { var optionValues = new Dictionary(); for (var i = 0; i < args.Length; i++) { if (!args[i].StartsWith("--")) { optionValues.Add("unnamed", args[i]); continue; } optionValues[args[i]] = args[i + 1]; i++; } return new OptionArgs { OptionValues = optionValues, Arguments = [] }; } private static void PrintOption(string optionLine, string description) { var terminalWidth = Console.WindowWidth; // Console.WriteLine(terminalWidth); // for (var i = 0; i < terminalWidth; i++) // Console.Write("_"); // Console.WriteLine(); const int columnWidth = 44; var descriptionWidth = terminalWidth - columnWidth; // Если название опции слишком длиное, перенести описание на следующую строку if (optionLine.Length > columnWidth) { Console.WriteLine(optionLine); var lines = SplitText(description, descriptionWidth); foreach (var line in lines) { Console.WriteLine($"{new string(' ', 2)}{line}"); } return; } var formatted = optionLine.PadRight(columnWidth); var descLines = SplitText(description, descriptionWidth); // Первая строка с опцией и началом описания Console.WriteLine($"{formatted}{descLines[0]}"); // Остальные строки описания с выравниванием for (var i = 1; i < descLines.Count; i++) { Console.WriteLine($"{new string(' ', columnWidth)}{descLines[i]}"); } Console.WriteLine(); } private static List SplitText(string text, int maxWidth) { var lines = new List(); if (maxWidth < 1) return [text]; var words = text.Split(' '); var current = ""; foreach (var word in words) { if ((current + word + " ").Length <= maxWidth) { current += word + " "; } else { if (!string.IsNullOrEmpty(current)) lines.Add(current.TrimEnd()); current = word + " "; } } if (!string.IsNullOrEmpty(current)) lines.Add(current.TrimEnd()); return lines.Count > 0 ? lines : [text]; } private void PrintHelp() { Console.WriteLine("RTCSync - утилита для работы с часами реального времени DS3231, подключенными по шине I^2C через CH431. Требует winusb драйвер.\n"); Console.WriteLine("Использование: RTCSync.cli.exe <параметр> [опции]\n"); Console.WriteLine("Параметры:"); foreach (var cmd in _registredOptions.Values.Distinct()) { var optionNames = cmd.OptionNames.Aggregate((current, next) => current + ", " + next); var optionLine = $" {optionNames} {cmd.OptionValues}"; PrintOption(optionLine, cmd.Description); // Console.WriteLine($" {cmd.OptionNames.Aggregate((current, next) => current + $" {cmd.OptionValues}, " + next + $" {cmd.OptionValues}"), -54} {cmd.Description}"); } Console.WriteLine("\nПримеры:"); Console.WriteLine(" RTCSync.cli.exe --set-time"); Console.WriteLine(" RTCSync.cli.exe -s"); Console.WriteLine(" RTCSync.cli.exe --set-time 0"); Console.WriteLine(" RTCSync.cli.exe -s 0"); } }