/// <summary> /// Initialises a new instance of the <see cref="CommandLineOption{T}"/> class. /// </summary> /// <param name="shortName">The short name for this Option or <c>null</c> if not required. Either <paramref name="shortName"/> or <paramref name="longName"/> must not be <c>null</c>, <c>empty</c> or contain only <c>whitespace</c>.</param> /// <param name="longName">The long name for this Option or <c>null</c> if not required. Either <paramref name="shortName"/> or <paramref name="longName"/> must not be <c>null</c>, <c>empty</c> or contain only <c>whitespace</c>.</param> /// <param name="parser">The parser to use for this Option.</param> /// <exception cref="ArgumentOutOfRangeException">Thrown if both <paramref name="shortName"/> and <paramref name="longName"/> are <c>null</c>, <c>empty</c> or contain only <c>whitespace</c>.</exception> /// <exception cref="ArgumentNullException">If <paramref name="parser"/> is <c>null</c>.</exception> public CommandLineOption(string shortName, string longName, ICommandLineOptionParser <T> parser) { if (parser == null) { throw new ArgumentNullException("parser"); } this.ShortName = shortName; this.LongName = longName; this.Parser = parser; }
/// <summary> /// Adds the specified <see cref="ICommandLineOptionParser{T}"/> to this factories list of supported parsers. /// If an existing parser has already been registered for the type then it will be replaced. /// </summary> /// <typeparam name="T">The type which the <see cref="ICommandLineOptionParser{T}"/> will be returned for.</typeparam> /// <param name="parser">The parser to return for the specified type.</param> /// <exception cref="ArgumentNullException">If <paramref name="parser"/> is <c>null</c>.</exception> public void AddOrReplace <T>(ICommandLineOptionParser <T> parser) { if (parser == null) { throw new ArgumentNullException("parser"); } var parserType = typeof(T); // remove existing this.Parsers.Remove(parserType); this.Parsers.Add(parserType, parser); }
internal static ICommandLineOptionParser <T> FindParser <T>() { ICommandLineOptionParser <T>?parser = null; var optionType = typeof(T); var parserType = optionType.Assembly.GetType($"{optionType.FullName}Parser", false, false); // 尝试从目标程序集中查找一个命令行解析器。 if (parserType != null) { parser = Activator.CreateInstance(parserType) as ICommandLineOptionParser <T>; } // 如果找不到目标命令行解析器,那么就使用内置的运行时解析器。 return(parser ?? RuntimeCommandLineOptionParser <T> .Create()); }
public T As <T>(ICommandLineOptionParser <T> parser) { if (parser == null) { throw new ArgumentNullException(nameof(parser)); } foreach (var optionValue in _optionArgs) { var option = optionValue.Key; var values = optionValue.Value; var valueCount = values?.Count ?? 0; if (option.Length == 0) { // 没有选项,只有值。 // 包括此 if 分支之外的任何情况下,值都需要保持传入时的大小写。 if (valueCount > 0) { if (parser.Verb is null) { parser.SetValue(values !); } else { parser.SetValue(values !.Skip(1).ToList()); } } } else if (option.Length == 1) { // 短名称。 var shortName = option[0]; if (parser is IRawCommandLineOptionParser <T> rawParser) { rawParser.SetValue(shortName, values); } else { if (valueCount == 0) { parser.SetValue(shortName, true); } else if (valueCount == 1) { if (bool.TryParse(values ![0], out var @bool))
public static CommandLineHandlerBuilder AddHandler <TVerb>( this ICommandLineHandlerBuilder builder, Action <TVerb> handler, ICommandLineOptionParser <TVerb>?parser = null) { if (builder is null) { throw new ArgumentNullException(nameof(builder)); } builder.CommandLine.AddMatch <TVerb>(new CommandLineTypeMatcher <Task <int> >(typeof(TVerb), verb => MatchWithHandler(builder.CommandLine, verb, options => Invoke(handler, options), parser))); return(builder switch { CommandLineHandlerBuilder commandLineBuilder => commandLineBuilder, CommandLine commandLine => new CommandLineHandlerBuilder(commandLine), _ => throw new NotSupportedException($"接口 {nameof(ICommandLineHandlerBuilder)} 不支持第三方实现。"), });
internal static CommandLineTypeMatchResult <int> MatchWithHandler <TVerb>(CommandLine commandLine, string?possibleVerb, Func <TVerb, int> handler, ICommandLineOptionParser <TVerb>?parser) { if (handler == null) { throw new ArgumentNullException(nameof(handler)); } // 为命令行参数类型寻找解析器。 parser ??= FindParser <TVerb>(); // 尝试匹配谓词,并执行处理器代码。 if (string.Equals(possibleVerb, parser.Verb, StringComparison.InvariantCultureIgnoreCase)) { return(new CommandLineTypeMatchResult <int>(VerbMatchingResult.Matched, typeof(TVerb), possibleVerb, () => handler(commandLine.As(parser)))); } if (parser.Verb is null) { return(new CommandLineTypeMatchResult <int>(VerbMatchingResult.FallbackMatched, typeof(TVerb), possibleVerb, () => handler(commandLine.As(parser)))); } return(new CommandLineTypeMatchResult <int>(VerbMatchingResult.NotMatch, typeof(TVerb), possibleVerb)); }
internal static CommandLineTypeMatchResult <int> MatchWithHandler <TVerb>(CommandLine commandLine, string?possibleVerb, Action <TVerb> handler, ICommandLineOptionParser <TVerb>?parser) { return(MatchWithHandler(commandLine, possibleVerb, verb => { handler(verb); return 0; }, parser)); }
internal static CommandLineFilterMatch MatchFilter <TFilter>(CommandLine commandLine, ICommandLineOptionParser <TFilter>?parser) where TFilter : ICommandLineFilter { return(new CommandLineFilterMatch(typeof(TFilter), () => commandLine.As(parser ?? FindParser <TFilter>()))); }
internal static CommandLineTypeMatchResult <Task <int> > MatchWithHandler <TVerb>(CommandLine commandLine, string?possibleVerb, Func <TVerb, Task> handler, ICommandLineOptionParser <TVerb>?parser) { return(MatchWithHandler(commandLine, possibleVerb, async verb => { await handler(verb).ConfigureAwait(false); return 0; }, parser)); }