/// <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());
        }
Ejemplo n.º 4
0
        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))
Ejemplo n.º 5
0
        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));
 }