146 lines
4.7 KiB
C#
146 lines
4.7 KiB
C#
namespace RTCSync.Options;
|
|
|
|
public class OptionDispatcher
|
|
{
|
|
private readonly Dictionary<string, IOption> _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<string, string>();
|
|
|
|
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<string> SplitText(string text, int maxWidth)
|
|
{
|
|
var lines = new List<string>();
|
|
|
|
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");
|
|
}
|
|
}
|