/// <summary> /// Adds a new option to the <see cref="CommandBuilder{TOption}"/> and returns an <see cref="OptionBuilder{TOption, TProp}"/> /// to configure that option with /// </summary> /// <typeparam name="TProp"></typeparam> /// <param name="shortName"> The short name of the option to be created </param> /// <param name="selector"> /// a property selector that points to the property that will be set when a value is found in the parsing stream matcing /// this option /// </param> /// <exception cref="ArgumentException"> <paramref name="shortName"/> is invalid </exception> /// <exception cref="ArgumentException"> <paramref name="selector"/> is not a valid <see cref="PropertySelector{TInput, TProp} "/></exception> /// <exception cref="ArgumentNullException"> <paramref name="selector"/> is null </exception> /// <returns> a new <see cref="OptionBuilder{TOption, TProp}"/> with the given name set </returns> public OptionBuilder <TOption, TProp> AddOption <TProp>(char shortName, Expression <Func <TOption, TProp> > selector) { var builder = new OptionBuilder <TOption, TProp>(shortName, selector); _builders.Add(builder); return(builder); }
/// <summary> Sets a custom parser to be used to parse the string inputs </summary> /// <typeparam name="TOption"> The underlying option type containing the property <typeparamref name="TProp"/> </typeparam> /// <typeparam name="TProp"> The type of the property that the built <typeparamref name="TOption"/> maps to </typeparam> /// <param name="builder"> The <see cref="OptionBuilder{TOption, TProp}"/> that you want to configure </param> /// <param name="parser"> /// The parser that will be used to convert commandline inputs to values of type <typeparamref name="TProp"/> /// </param> /// <exception cref="ArgumentNullException"> <paramref name="builder"/> or <paramref name="parser"/> are null </exception> /// <returns> The input <see cref="OptionBuilder{TOption, TProp}"/></returns> /// <remarks> If no parser is set a default <see cref="TypeConverter"/> will be reflected </remarks> public static OptionBuilder <TOption, TProp> WithParser <TOption, TProp>( this OptionBuilder <TOption, TProp> builder, Func <string, TProp> parser) where TOption : notnull { if (builder == null) { throw new ArgumentNullException(nameof(builder)); } builder.Parser = parser ?? throw new ArgumentNullException(nameof(parser)); return(builder); }
/// <summary> Sets the short name for the option being built </summary> /// <typeparam name="TOption"> The underlying option type containing the property <typeparamref name="TProp"/> </typeparam> /// <typeparam name="TProp"> The type of the property that the built <typeparamref name="TOption"/> maps to </typeparam> /// <param name="builder"> The <see cref="OptionBuilder{TOption, TProp}"/> that you want to configure </param> /// <param name="shortName"> The long name of the option </param> /// <exception cref="ArgumentException"> <paramref name="shortName"/> is not a valid long name for a flag </exception> /// <exception cref="InvalidOperationException"> <paramref name="builder"/> has had a its short name set previously </exception> /// <exception cref="ArgumentNullException"> <paramref name="builder"/> or <paramref name="shortName"/> are <c>null</c></exception> /// <returns> The input <see cref="OptionBuilder{TOption, TProp}"/></returns> public static OptionBuilder <TOption, TProp> WithShortName <TOption, TProp>(this OptionBuilder <TOption, TProp> builder, char shortName) where TOption : notnull { if (builder == null) { throw new ArgumentNullException(nameof(builder)); } builder.ShortName = OptionName.Parse(shortName.ToString()) as OptionName.Short ?? throw new ArgumentException($"Could not convert value to short name '{shortName}'", nameof(shortName)); return(builder); }
/// <summary> Sets the long name for the option being built </summary> /// <typeparam name="TOption"> The underlying option type containing the property <typeparamref name="TProp"/> </typeparam> /// <typeparam name="TProp"> The type of the property that the built <typeparamref name="TOption"/> maps to </typeparam> /// <param name="builder"> The <see cref="OptionBuilder{TOption, TProp}"/> that you want to configure </param> /// <param name="longName"> The long name of the option </param> /// <exception cref="ArgumentException"> If <paramref name="longName"/> is not a valid long name for an option </exception> /// <exception cref="InvalidOperationException"> <paramref name="builder"/> has had a its long name set previously </exception> /// <exception cref="ArgumentNullException"> if <paramref name="builder"/> or <paramref name="longName"/> are <c>null</c></exception> /// <returns> The input <see cref="OptionBuilder{TOption, TProp}"/></returns> public static OptionBuilder <TOption, TProp> WithLongName <TOption, TProp>(this OptionBuilder <TOption, TProp> builder, string longName) where TOption : notnull { if (builder == null) { throw new ArgumentNullException(nameof(builder)); } builder.LongName = OptionName.Parse(longName) as OptionName.Long ?? throw new ArgumentException($"Could not convert value to long name '{longName}'", nameof(longName)); return(builder); }
/// <summary> /// Sets a property on the parent <typeparamref name="TOption"/> that is incompatible with this option /// </summary> /// <typeparam name="TOption"> The underlying option type containing the property <typeparamref name="TProp"/> </typeparam> /// <typeparam name="TProp"> The type of the property that the built <typeparamref name="TOption"/> maps to </typeparam> /// <typeparam name="TTarget"> The type of the paramter to be precluded </typeparam> /// <param name="builder"> The <see cref="OptionBuilder{TOption, TProp}"/> that you want to configure </param> /// <param name="expression"> /// A property selector expression that targets the incompatible property on the <typeparamref name="TOption"/> /// </param> /// <exception cref="ArgumentNullException"> <paramref name="builder"/> or <paramref name="expression"/> are null </exception> /// <exception cref="ArgumentException"> /// <paramref name="expression"/> is not a property selector expression targeting a property that is both /// readable and writeable /// </exception> /// <returns> The input <see cref="OptionBuilder{TOption, TProp}"/></returns> public static OptionBuilder <TOption, TProp> Precludes <TOption, TProp, TTarget>( this OptionBuilder <TOption, TProp> builder, Expression <Func <TOption, TTarget> > expression) where TOption : notnull { if (builder == null) { throw new ArgumentNullException(nameof(builder)); } var selector = new PropertySelector <TOption, TTarget>(expression); var rule = new Rule(RuleKind.Precludes, builder.Selector.MemberName, selector.MemberName); builder.Rules.Add(rule); return(builder); }